PHP wddx_deserialize() String Append Buffer Overflow Vulnerability

QQ空间 新浪微博 微信 QQ facebook twitter
漏洞ID 1053022 漏洞类型
发布时间 2007-03-05 更新时间 2007-03-05
漏洞平台 N/A CVSS评分 N/A
Since Stefan Esser left the PHP Security Response Team there have been countless of pseudo security fixes to the PHP CVS. With pseudo security fixes we mean replacing safe calls of functions considered unsafe (like strncpy, sprintf) with calls to functions considered more secure (e.g. strlcpy, spprintf).

Unfortunately these changes were done very sloppy and had to be reverted in several places, because they actually broke the underlying code and some user complained about it. There is however a place within the WDDX extension where a buffer overflow was introduced to the code that can be triggered by specially crafted (malformed) WDDX packets. Because of this it is very unlikely that a user will complain about it and therefore without this advisory it would most probably make it into the next PHP release.

During the last week the following strncpy -> strlcpy change was added to the CVS that is completely broken.

--- wddx.c	2007/02/24 02:17:27
+++ wddx.c	2007/02/24 17:59:45
@@ -16,7 +16,7 @@
-/* $Id: wddx.c,v 2007/02/24 02:17:27 helly Exp $ */
+/* $Id: wddx.c,v 2007/02/24 17:59:45 iliaa Exp $ */
 #include "config.h"
@@ -1034,10 +1034,9 @@
    Z_STRVAL_P(ent->data) = estrndup(decoded, decoded_len);
    Z_STRLEN_P(ent->data) = decoded_len;
 } else {
-   Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data),
-   Z_STRLEN_P(ent->data) + decoded_len + 1);
-   strncpy(Z_STRVAL_P(ent->data)+Z_STRLEN_P(ent->data), decoded, decoded_len);
    Z_STRLEN_P(ent->data) += decoded_len;
+   Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data), Z_STRLEN_P(ent->data) + 1);
+   strlcpy(Z_STRVAL_P(ent->data) + Z_STRLEN_P(ent->data), decoded, Z_STRLEN_P(ent->data) + 1);
    Z_STRVAL_P(ent->data)[Z_STRLEN_P(ent->data)] = '\0';

For any C programmer it should be obvious that the bold marked places are wrong. The correct function to call would be strlcat(), not strlcpy() and the additive term is wrong, too.

Because of this little glitch the WDDX deserialisation code does now contain a buffer overflow that is triggered by for example a <string> tag that is interrupted by another tag. A situation that will only occur in malformed (attacker supplied) WDDX packets.
Proof of concept, exploit or instructions to reproduce

Because this vulnerability exists only within the CVS version of PHP and we just did find it we did not create a code execution exploit yet. We however do not doubt that such an exploit is possible and will most probably provide proof until the end of this month. Until then you can play with the attached POC that just crashs PHP in the memory manager.

We can understand that the PHP developers perfom all these changes to the PHP source in order to make it more secure. But we urge them to check their changes multiple times before commiting. Changed like the WDDX case are very dangerous, because they are only triggered by malformed packets and therefore they won't be found unless a security audit reveals them.

And with changes like these they only prove our points.

SecurityReason Note :
Exploit -