PHP是广泛使用的通用目的脚本语言,特别适合于Web开发,可嵌入到HTML中。 PHP在处理会话信息的功能函数实现上存在漏洞,远程攻击者可能利用此漏洞读取敏感信息或向非授权位置写入文件。 可以在PHP的ini_set()中定义用于保存会话路径的session_save_path()函数。在session.save_path中必须要存在用于保存tmp文件的路径,但session.save_path的句法可能为: [/PATH] 或 [N;/PATH] N - 可以是一个串 例如: 1. session_save_path(\"/DIR/WHERE/YOU/HAVE/ACCESS\") 2. session_save_path(\"5;/DIR/WHERE/YOU/HAVE/ACCESS\") 3. session_save_path(\"/DIR/WHERE/YOU/DONT/HAVE/ACCESS\0;/DIR/WHERE/YOU/HAVE/ACCESS\") PHP520 ext/session/session.c中代码: - -1477-1493--- PHP_FUNCTION(session_save_path) { zval **p_name; int ac = ZEND_NUM_ARGS(); char *old; if (ac < 0 || ac > 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) WRONG_PARAM_COUNT; old = estrdup(PS(save_path)); if (ac == 1) { convert_to_string_ex(p_name); zend_alter_ini_entry(\"session.save_path\", sizeof(\"session.save_path\"), \ Z_STRVAL_PP(p_name), Z_STRLEN_PP(p_name), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } RETVAL_STRING(old, 0); } - -1477-1493---...
PHP是广泛使用的通用目的脚本语言,特别适合于Web开发,可嵌入到HTML中。 PHP在处理会话信息的功能函数实现上存在漏洞,远程攻击者可能利用此漏洞读取敏感信息或向非授权位置写入文件。 可以在PHP的ini_set()中定义用于保存会话路径的session_save_path()函数。在session.save_path中必须要存在用于保存tmp文件的路径,但session.save_path的句法可能为: [/PATH] 或 [N;/PATH] N - 可以是一个串 例如: 1. session_save_path(\"/DIR/WHERE/YOU/HAVE/ACCESS\") 2. session_save_path(\"5;/DIR/WHERE/YOU/HAVE/ACCESS\") 3. session_save_path(\"/DIR/WHERE/YOU/DONT/HAVE/ACCESS\0;/DIR/WHERE/YOU/HAVE/ACCESS\") PHP520 ext/session/session.c中代码: - -1477-1493--- PHP_FUNCTION(session_save_path) { zval **p_name; int ac = ZEND_NUM_ARGS(); char *old; if (ac < 0 || ac > 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) WRONG_PARAM_COUNT; old = estrdup(PS(save_path)); if (ac == 1) { convert_to_string_ex(p_name); zend_alter_ini_entry(\"session.save_path\", sizeof(\"session.save_path\"), \ Z_STRVAL_PP(p_name), Z_STRLEN_PP(p_name), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } RETVAL_STRING(old, 0); } - -1477-1493--- 值被设置为了hash_memory,但在这之前,safe_mode和open_basedir会检查这个值。如果用户启动了会话的话(如session_start()),PS_OPEN_FUNC(files)函数会检查session.save_path的值。 PHP520 ext/session/mod_files.c中代码: - -242-300--- PS_OPEN_FUNC(files) { ps_files *data; const char *p, *last; const char *argv[3]; int argc = 0; size_t dirdepth = 0 int filemode = 0600; if (*save_path == \'\'\0\'\') { /* if save path is an empty string, determine the temporary dir */ save_path = php_get_temporary_directory(); } /* split up input parameter */ last = save_path; p = strchr(save_path, \'\';\'\'); while (p) { argv[argc++] = last; last = ++p; p = strchr(p, \'\';\'\'); if (argc > 1) break; } argv[argc++] = last; if (argc > 1) { errno = 0; dirdepth = (size_t) strtol(argv[0], NULL, 10); if (errno == ERANGE) { php_error(E_WARNING, \"The first parameter in session.save_path is invalid\"); return FAILURE; } } if (argc > 2) { errno = 0; filemode = strtol(argv[1], NULL, 8); if (errno == ERANGE || filemode < 0 || filemode > 07777) { php_error(E_WARNING, \"The second parameter in session.save_path is invalid\"); return FAILURE; } } save_path = argv[argc - 1]; data = emalloc(sizeof(*data)); memset(data, 0, sizeof(*data)); data->fd = -1; data->dirdepth = dirdepth; data->filemode = filemode; data->basedir_len = strlen(save_path); data->basedir = estrndup(save_path, data->basedir_len); PS_SET_MOD_DATA(data); return SUCCESS; } - -242-300--- 由于在session.save_path中\";\"之前有一个空字节,strchr()就无法看到\";\",因此路径就成了/DIR/WHERE/YOU/DONT/HAVE/ACCESS。