安全研究

安全漏洞
PHP session.save_path()函数绕过safe_mode及open_basedir安全限制漏洞

发布日期:2006-12-08
更新日期:2006-12-11

受影响系统:
PHP PHP 5.2.0
描述:
BUGTRAQ  ID: 21508
CVE(CAN) ID: CVE-2006-6383

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。


<*来源:Maksymilian Arciemowicz (max@jestsuper.pl
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=116561808502440&w=2
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

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")

建议:
厂商补丁:

PHP
---
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://www.php.net

浏览次数:2965
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障