Advisory: Multiple Remote Vulnerabilities in Wordpress
Advisory ID: 4tphi-sa-20070111-wordpress
Release Date: 01-24-2007
Author: Blake Matheny (bmatheny (at) mobocracy (dot) net [email concealed])
Software: WordPress < 2.1
Impact: Remote & Local DoS, File Disclosure
Overview:
From Wikipedia, "WordPress is a blog publishing system written in PHP
and backed by a MySQL database."
Multiple vulnerabilities exist in the XMLRPC and Pingback
implementation that are included with Wordpress. Note that some issues
discovered with Pingback affect other vendors as well. Please see
the following advisory for details: 4tphi-sa-20070111-pingback
Details:
WordPress is vulnerable to the attacks described in the pingback
advisory. In testing, a single PC on a T1 connection was able to cripple
two dual Xeon apache servers on separate 100Mb connection. This was
accomplished by sending out multiple requests to server A specifying a
sourceURI on server B that was a 1GB media file. This attack utilizes
resources on server A and server B, but not the malicious users machine.
Additionally, WordPress does not sanitize the sourceURI before passing
it to wp_remote_fopen(); This makes it possible to specify non-HTTP
resources to be read such as local files or ftp sources. In particular, a
malicious user can determine whether certain files exist on the local file
system. For example, the following request would help determine the
version of Linux being used:
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param>
<value><string>/etc/SuSE-release</string></value>
</param>
<param>
<value><string>http://b.example.com/#p</string></value>
</param>
</params>
</methodCall>
If this file does not exist, fault 16 (source URI does not exist) will be
returned and if it does exist it is likely that fault 17 (source URI does
not contain a link to the target URI) will be returned. This works
whether curl or the fopen() stream is used, only the uri has to be
changed. This will not work if the webserver user can not read the file.
If the administrator has allowed automatic pingbacks to show up as
comments, it is possible for an attacker to have system information
display in that comment. For instance, an attacker could request a url on
the host with the following text in it:
<title>example</title><a href="valid targetURI">text</a>
If that showed up in the apache access_log or error_log, and the
webserver user had permission to read that file the above XMLRPC request,
after determining the OS, could specify the log as the sourceURI. This
would cause some of the log file to be displayed as a comment. The session
file for PHP would be a good target.
Recommendations:
Upgrade to Wordpress 2.1. The original recommendations made to the
Wordpress security team can be found below. Please note that Wordpress
still does not check the content type, however the timeout has been set to
10 seconds and as such the impact of binary files is minimized.
The local file issues can be resolved by ensuring that the URI scheme
is HTTP. This also disallows other resources, such as ftp, from being
read. In order to prevent overly large files from being retrieved, a
reasonable timeout for curl and fopen should be set. Also, if content is
missing a compatible Content-Type (such as text/xml) it should not be read
as it can not be parsed. The attached patch is one possible solution to
the issues described above. There are some more significant design
problems, particularly with respect to pingback authentication. These are
described in the pingback advisory and are not addressed here, as there
has been no formal specification modification yet.
Disclosure Timeline:
01-24-2007 - Released
01-18-2007 - Response from Wordpress. Waiting on release of 2.1 to
disclose. Code base includes patch.
01-14-2007 - Notified security (at) wordpress (dot) org [email concealed]
References:
4tphi-sa-20070111-pingback - Weaknesses in pingback design
4tphi-sa-20070111-wordpress.diff - Patch to partially fix issues
LEGAL NOTICES
This advisory is being provided to you under the RFPolicy documented at
http://www.wiretrip.net/rfp/policy.html. You are encouraged to read this
policy; however, in the interim, you have approximately 5 days to respond
to this initial email.
--
Blake Matheny
bmatheny (at) mobocracy (dot) net [email concealed]
http://mobocracy.net
diff -Nur wordpress.orig/wp-includes/functions.php wordpress/wp-includes/functions.php
--- wordpress.orig/wp-includes/functions.php 2007-01-13 21:24:05.749659500 -0800
+++ wordpress/wp-includes/functions.php 2007-01-13 21:43:41.855161500 -0800
@@ -2186,10 +2186,22 @@
}
function wp_remote_fopen( $uri ) {
+ $timeout = 10;
+ $parsed_url = @parse_url($uri);
+ if ( !$parsed_url || !is_array($parsed_url) )
+ {
+ return false;
+ }
+ if ( !isset($parsed_url['scheme']) ||
+ !in_array($parsed['scheme'], array('http','https')) )
+ {
+ $uri = 'http://' . $uri;
+ }
if ( ini_get('allow_url_fopen') ) {
$fp = @fopen( $uri, 'r' );
if ( !$fp )
return false;
+ stream_set_timeout($fp, $timeout);
$linea = '';
while( $remote_read = fread($fp, 4096) )
$linea .= $remote_read;
@@ -2200,8 +2212,11 @@
curl_setopt ($handle, CURLOPT_URL, $uri);
curl_setopt ($handle, CURLOPT_CONNECTTIMEOUT, 1);
curl_setopt ($handle, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt ($handle, CURLOPT_TIMEOUT, $timeout);
$buffer = curl_exec($handle);
curl_close($handle);
+ if ( !preg_match('/.*text/.*/', curl_getinfo($handle, CURLINFO_CONTENT_TYPE)) )
+ return '';
return $buffer;
} else {
return false;
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
iD8DBQFFt68y+1RMaZNdlgURAi0yAJ9OPwAkieV9Jq0n942MlH5u+qQ2oACeIdEo
gAloHB6gHrYnUMdauXPkM3I=
=dGKi
-----END PGP SIGNATURE-----