Réponse de Charlie Briggs
---------- Forwarded message ----------
From: Charlie Briggs <[email protected]>
Date: 2014/1/20
Subject: RE: Dotclear PHP Object Injection > Potential Remote Code Execution
To: Franck Paul <[email protected]>
Hi Franck,
Thanks for the quick response. Here is the patch that I cooked up:
# Password protected entry
if ($post_password != '' && !$_ctx->preview)
{
# Get passwords cookie
if (isset($_COOKIE['dc_passwd'])) {
$pwd_cookie = json_decode( $_COOKIE['dc_passwd'], true );
} else {
$pwd_cookie = array();
}
# Check for match
if ((!empty($_POST['password']) && $_POST['password'] ==
$post_password)
|| (isset($pwd_cookie[$post_id]) && $pwd_cookie[$post_id] ==
$post_password))
{
$pwd_cookie[$post_id] = $post_password;
setcookie('dc_passwd',json_encode( $pwd_cookie ),0,'/');
}
else
{
self::serveDocument('password-form.html','text/html',false);
return;
}
}
This calls json_decode with the ASSOC flag set to true, meaning it still
works in the same way as unserialize would, but without the unwanted
functionality of the object injection.
Regards,
Charlie Briggs
Security Consultant
MWR InfoSecurity
Mobile: +44 (0) 7584 558 782
*From:* Franck Paul [mailto:[email protected]]
*Sent:* 20 January 2014 11:51 AM
*To:* Charlie Briggs
*Subject:* Re: Dotclear PHP Object Injection > Potential Remote Code
Execution
Hi Charlie,
We commited a patch (see http://dev.dotclear.org/2.0/changeset/d60876d7e4e4)
and we will publish a new release (Dotclear 2.6.2) as soon as possible.
Thanks a lot again
Franck for the DC Team
2014/1/20 Franck Paul <[email protected]>
Hi Charlie,
Thanks a lot for reporting this and we will try to fix this as soon as
possible.
Franck for DC Team
2014/1/20 Charlie Briggs <[email protected]>
Hi there,
I recently came across Dotclear and decided to briefly look over its
security.
After doing some code review and grepping for common PHP pitfalls – calls
to exec, eval, system, passthru, preg_replace with the e modifier,
unescaped queries, calls to move_uploaded_file with no verification, and so
on, I found that in inc/public/lib.urlhandlers.php and
plugins/pages/_public.php there is a call to unserialize() which takes
direct user input via the cookies. For this call to go ahead, you need to
access a password-protected post/page.
# Password protected entry
if ($post_password != '' && !$_ctx->preview)
{
# Get passwords cookie
if (isset($_COOKIE['dc_passwd'])) {
$pwd_cookie =
unserialize($_COOKIE['dc_passwd']);
} else {
$pwd_cookie = array();
}
.....
}
Setting the dc_passwd cookie to a serialized object which does not exist,
O:4:"Test":0:{}, throws the PHP error “Cannot use object of type
__PHP_Incomplete_Class as array”. For a code execution proof-of-concept, if
we create the class “Test” and ensure it is loaded before the unserialize()
runs:
class Test
{
function __wakeup()
{
echo "Hello world";
}
}
The following output is given:
Hello world
Fatal error: Cannot use object of type Test as array in
/var/www/dotclear/dotclear/inc/public/lib.urlhandlers.php on line 389
I haven’t gone through all the loaded classes to see if any interesting
code execution can occur off-the-bat; however, as plugins can be loaded,
it’s possible that a plugin could cause this core vulnerability to become
exploitable.
I have rated the overall risk for this as medium, as it is
context-dependant – i.e. it only works on a password-protected post.
The recommended fix for this would be to use safe methods of data exchange,
such as PHP’s json_encode() / json_decode().
Regards,
Charlie Briggs
Security Consultant
MWR InfoSecurity
Mobile: +44 (0) 7584 558 782
--
Franck
--
Franck
--
Franck
--
Dev mailing list - [email protected] - http://ml.dotclear.org/listinfo/dev